diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list
index cad2aab88b..727fd22e74 100644
--- a/ci-scripts/cppcheck_suppressions.list
+++ b/ci-scripts/cppcheck_suppressions.list
@@ -37,6 +37,7 @@ memleak:openair2/UTIL/OMG/omg_hashtable.c
// _emm_as_encode function creates the encoded buffer
//
memleak:openair3/NAS/UE/EMM/SAP/emm_as.c
+memleak:openair1/PHY/INIT/nr_init_ue.c
//-----------------------------------------------------------------------------
//*****************************************************************************
// section for files not used in oai exec's included in CI.
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index ce37b0c8ba..56c6ebead8 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -332,12 +332,6 @@ class OaiCiTest():
logging.debug('Found a N3xx device --> resetting it')
SSH.command('cd ' + self.UESourceCodePath, '\$', 5)
# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
- # in case of NR-UE, we may have rrc_config_path (Temporary?)
- modifiedUeOptions = str(self.Initialize_OAI_UE_args)
- if RAN.Getair_interface() == 'nr':
- result = re.search('--rrc_config_path ', modifiedUeOptions)
- if result is not None:
- modifiedUeOptions = modifiedUeOptions.replace('rrc_config_path ', 'rrc_config_path ' + self.UESourceCodePath + '/')
SSH.command('source oaienv', '\$', 5)
SSH.command('cd cmake_targets/ran_build/build', '\$', 5)
if RAN.Getair_interface() == 'lte':
@@ -352,7 +346,17 @@ class OaiCiTest():
SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5)
SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5)
SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5)
- SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
+ else:
+ SSH.command('if [ -e rbconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
+ SSH.command('if [ -e rbconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
+ # Copy the RAW files from gNB running directory (maybe on another machine)
+ copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/rbconfig.raw', '.')
+ if (copyin_res == 0):
+ SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './rbconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build')
+ copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/reconfig.raw', '.')
+ if (copyin_res == 0):
+ SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './reconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build')
+ SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
self.UELogFile = 'ue_' + self.testCase_id + '.log'
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index 9d6349077f..9b9fe462f1 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -186,7 +186,7 @@ function variant__v3__phy_sim {
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=8192
VM_DISK=20
- RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b"
+ RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111 015112\" -q -np -b"
}
function variant__v4__cppcheck {
@@ -197,7 +197,7 @@ function variant__v4__cppcheck {
}
function variant__v5__gnb_usrp {
- VM_MEMORY=8192
+ VM_MEMORY=10240
VM_CPU=8
NB_PATTERN_FILES=9
BUILD_OPTIONS="--gNB -w USRP"
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 5f05a2ae4f..9c66b1863c 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -546,6 +546,9 @@ class RANManagement():
# Launch eNB with the modified config file
mySSH.command('source oaienv', '\$', 5)
mySSH.command('cd cmake_targets', '\$', 5)
+ if self.air_interface == 'nr':
+ mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
+ mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
@@ -804,6 +807,8 @@ class RANManagement():
uciStatMsgCount = 0
pdcpFailure = 0
ulschFailure = 0
+ ulschAllocateCCEerror = 0
+ uplinkSegmentsAborted = 0
ulschReceiveOK = 0
gnbRxTxWakeUpFailure = 0
cdrxActivationMessageCount = 0
@@ -922,6 +927,12 @@ class RANManagement():
result = re.search('ULSCH in error in round|ULSCH 0 in error', str(line))
if result is not None:
ulschFailure += 1
+ result = re.search('ERROR ALLOCATING CCEs', str(line))
+ if result is not None:
+ ulschAllocateCCEerror += 1
+ result = re.search('uplink segment error.*aborted [1-9] segments', str(line))
+ if result is not None:
+ uplinkSegmentsAborted += 1
result = re.search('ULSCH received ok', str(line))
if result is not None:
ulschReceiveOK += 1
@@ -965,6 +976,14 @@ class RANManagement():
statMsg = nodeB_prefix + 'NB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
htmleNBFailureMsg += statMsg + '\n'
+ if ulschAllocateCCEerror > 0:
+ statMsg = nodeB_prefix + 'NB showed ' + str(ulschAllocateCCEerror) + ' "eNB_dlsch_ulsch_scheduler(); ERROR ALLOCATING CCEs" message(s)'
+ logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+ htmleNBFailureMsg += statMsg + '\n'
+ if uplinkSegmentsAborted > 0:
+ statMsg = nodeB_prefix + 'NB showed ' + str(uplinkSegmentsAborted) + ' "uplink segment error 0/2, aborted * segments" message(s)'
+ logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
+ htmleNBFailureMsg += statMsg + '\n'
if dropNotEnoughRBs > 0:
statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
diff --git a/ci-scripts/rrc-files/rbconfig.raw b/ci-scripts/rrc-files/rbconfig.raw
deleted file mode 100644
index b03f18d121..0000000000
Binary files a/ci-scripts/rrc-files/rbconfig.raw and /dev/null differ
diff --git a/ci-scripts/rrc-files/reconfig.raw b/ci-scripts/rrc-files/reconfig.raw
deleted file mode 100644
index 97b41d9b6b..0000000000
Binary files a/ci-scripts/rrc-files/reconfig.raw and /dev/null differ
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 591649b655..0db2264c76 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -89,6 +89,9 @@ function start_basic_sim_enb {
fi
done
ENB_SYNC=0
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -151,6 +154,9 @@ function start_basic_sim_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1
rm $1
if [ $i -lt 50 ]
then
@@ -760,6 +766,9 @@ function start_l2_sim_enb {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1
rm $1
ENB_SYNC=1
if [ $i -lt 50 ]
@@ -868,6 +877,9 @@ function start_l2_sim_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1
rm $1
UE_SYNC=1
if [ $i -lt 50 ]
@@ -981,6 +993,9 @@ function start_rf_sim_enb {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -1110,6 +1125,9 @@ function start_rf_sim_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -1154,6 +1172,10 @@ function start_rf_sim_gnb {
local LOC_CONF_FILE=$5
# 1 is with S1 and 0 without S1 aka noS1
local LOC_S1_CONFIGURATION=$6
+
+ if [ -e rbconfig.raw ]; then rm -f rbconfig.raw; fi
+ if [ -e reconfig.raw ]; then rm -f reconfig.raw; fi
+
echo "cd /home/ubuntu/tmp" > $1
echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1
echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1
@@ -1167,6 +1189,7 @@ function start_rf_sim_gnb {
echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1
echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
+ echo "sudo rm -f r*config.raw" >> $1
if [ $LOC_S1_CONFIGURATION -eq 0 ]
then
echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1
@@ -1227,6 +1250,13 @@ function start_rf_sim_gnb {
fi
fi
sleep 10
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1
+ rm $1
+ # Copy the RAW files from the gNB run for the NR-UE
+ scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/rbconfig.raw .
+ scp -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/ran_build/build/reconfig.raw .
}
function start_rf_sim_nr_ue {
@@ -1237,14 +1267,21 @@ function start_rf_sim_nr_ue {
local LOC_FREQUENCY=$6
# 1 is with S1 and 0 without S1 aka noS1
local LOC_S1_CONFIGURATION=$7
+
+ # Copy the RAW files from the gNB run
+ scp -o StrictHostKeyChecking=no rbconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
+ scp -o StrictHostKeyChecking=no reconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
+
echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1
echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1
echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1
echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
+ echo "sudo cp /home/ubuntu/tmp/r*config.raw /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
+ echo "sudo chmod 666 /home/ubuntu/tmp/cmake_targets/ran_build/build/r*config.raw" >> $1
echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1
if [ $LOC_S1_CONFIGURATION -eq 0 ]
then
- echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/ci-scripts/rrc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
+ echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
fi
echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
echo "cat ./my-nr-softmodem-run.sh" >> $1
@@ -1291,6 +1328,9 @@ function start_rf_sim_nr_ue {
i=$[$i+1]
fi
done
+ echo "echo \"free -m\"" > $1
+ echo "free -m" >> $1
+ ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1
rm $1
if [ $i -lt 50 ]
then
@@ -2024,7 +2064,7 @@ function run_test_on_vm {
NR_STATUS=0
######### start of loop
- while [ $try_cnt -lt 5 ]
+ while [ $try_cnt -lt 1 ]
do
SYNC_STATUS=0
PING_STATUS=0
@@ -2046,6 +2086,8 @@ function run_test_on_vm {
echo "Problem w/ gNB and NR-UE not syncing"
terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+ scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
+ scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
SYNC_STATUS=-1
try_cnt=$[$try_cnt+1]
continue
@@ -2085,6 +2127,8 @@ function run_test_on_vm {
echo "DL test not OK"
terminate_enb_ue_basic_sim $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 2
terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1
+ scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC
+ scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC
try_cnt=$[$try_cnt+1]
continue
fi
diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
index f3e80c576a..c51093c178 100644
--- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
+++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml
@@ -52,7 +52,7 @@
Initialize_OAI_UE
Initialize NR UE USRP
- --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path ci-scripts/rrc-files
+ --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path .
NR
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 4f1a035de4..525c9eae56 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1674,7 +1674,7 @@ add_library(PHY_MEX ${PHY_MEX_UE} ${CONFIG_LIB})
#Layer 2 library
#####################
set(MAC_DIR ${OPENAIR2_DIR}/LAYER2/MAC)
-set(NR_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
+set(NR_GNB_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
set(NR_UE_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_UE)
set(PHY_INTERFACE_DIR ${OPENAIR2_DIR}/PHY_INTERFACE)
set(NR_PHY_INTERFACE_DIR ${OPENAIR2_DIR}/NR_PHY_INTERFACE)
@@ -1836,14 +1836,15 @@ set (MAC_SRC
set (MAC_NR_SRC
${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c
- ${NR_MAC_DIR}/main.c
- ${NR_MAC_DIR}/config.c
- ${NR_MAC_DIR}/gNB_scheduler.c
- ${NR_MAC_DIR}/gNB_scheduler_bch.c
- ${NR_MAC_DIR}/gNB_scheduler_dlsch.c
- ${NR_MAC_DIR}/gNB_scheduler_ulsch.c
- ${NR_MAC_DIR}/gNB_scheduler_primitives.c
- ${NR_MAC_DIR}/gNB_scheduler_phytest.c
+ ${NR_GNB_MAC_DIR}/main.c
+ ${NR_GNB_MAC_DIR}/config.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_bch.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_dlsch.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_ulsch.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_primitives.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_phytest.c
+ ${NR_GNB_MAC_DIR}/gNB_scheduler_RA.c
)
@@ -1855,7 +1856,6 @@ set (MAC_SRC_UE
${MAC_DIR}/l1_helpers.c
${MAC_DIR}/rar_tools_ue.c
${MAC_DIR}/config_ue.c
-
)
set (MAC_NR_SRC_UE
@@ -1865,6 +1865,9 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/main_ue_nr.c
${NR_UE_MAC_DIR}/nr_ue_procedures.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
+ ${NR_UE_MAC_DIR}/nr_l1_helpers.c
+ ${NR_UE_MAC_DIR}/nr_ra_procedures.c
+ ${NR_UE_MAC_DIR}/rar_tools_nrUE.c
)
set (ENB_APP_SRC
@@ -1928,7 +1931,7 @@ add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c)
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
-include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
+include_directories("${OPENAIR2_DIR}/LAYER2")
include_directories("${OPENAIR1_DIR}/SCHED_NR_UE")
#include_directories("${NFAPI_USER_DIR}"")
@@ -1956,6 +1959,19 @@ set (GTPV1U_SRC
add_library(GTPV1U ${GTPV1U_SRC})
add_dependencies(GTPV1U rrc_flag)
+#NR case
+set (NR_GTPV1U_SRC
+ ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c
+ ${RRC_DIR}/rrc_eNB_GTPV1U.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c
+ ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c
+ ${GTPV1U_DIR}/gtpv1u_teid_pool.c
+)
+add_library(NR_GTPV1U ${NR_GTPV1U_SRC})
+add_dependencies(NR_GTPV1U rrc_flag)
+
set (MME_APP_SRC
${OPENAIR3_DIR}/MME_APP/mme_app.c
${OPENAIR3_DIR}/MME_APP/mme_config.c
@@ -2708,6 +2724,7 @@ add_executable(nr-softmodem
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
+ ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
@@ -2721,7 +2738,7 @@ add_executable(nr-softmodem
target_link_libraries (nr-softmodem
-Wl,--start-group
- UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
+ UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
@@ -2765,9 +2782,9 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
+ PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
+ NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
- PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON S1AP_LIB S1AP_ENB
- NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES})
@@ -2943,7 +2960,7 @@ add_executable(nr_prachsim
${T_SOURCE}
${SHLIB_LOADER_SOURCES})
target_link_libraries(nr_prachsim
- -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
+ -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt
index 10c14fd59a..19a333c626 100644
--- a/cmake_targets/autotests/README.txt
+++ b/cmake_targets/autotests/README.txt
@@ -142,10 +142,14 @@ Obj.# Case# Test# Description
(Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%))
(TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
(TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
-01 51 11 nr_ulsim Test cases. (Test1: MCS 9),
- (Test2: MCS 16),
- (Test3: MCS 28)
-
+01 51 11 nr_ulsim Test cases. (Test1: MCS 9 106 PRBs),
+ (Test2: MCS 16 50 PRBs),
+ (Test3: MCS 28 50 PRBs),
+ (Test4: MCS 9 217 PRBs),
+ (Test5: MCS 9 273 PRBs)
+01 51 12 nr_prachsim Test cases.(Test1: 106 PRBs),
+ (Test2: 217 PRBs),
+ (Test3: 273 PRBs)
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 882670727b..497e9f053b 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1036,7 +1036,9 @@
execution
polartest Test cases. (Test1: PBCH polar test),
- (Test2: DCI polar test)
+ (Test2: DCI polar test),
+ (Test3: UCI polar test,6-bit CRC),
+ (Test4: UCI polar test,11-bit CRC)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1044,8 +1046,10 @@
$OPENAIR_DIR/targets/bin/polartest.Rel15
-q -s-10 -f0
- -q -s-10 -f0 -m1
- polartest.test1 polartest.test2
+ -q -s-10 -f0 -m1
+ -q -s-2 -f2 -m2 -k12
+ -q -s-2 -f2 -m2 -k20
+ polartest.test1 polartest.test2 polartest.test3 polartest.test4
BLER= 0.000000
segmentation fault|assertion|exiting|fatal
3
@@ -1179,15 +1183,20 @@
nr_pucchsim Test cases. (Test1: Format 0 1-bit ACK miss 106 PRB),
(Test2: Format 0 2-bit ACK miss 106 PRB),
(Test3: Format 0 2-bit ACK miss, 1-bit SR 106 PRB),
- (Test4: Format 2 3-bit 106 PRB),
- (Test5: Format 2 4-bit 106 PRB),
- (Test6: Format 2 5-bit 106 PRB),
- (Test7: Format 2 6-bit 106 PRB),
- (Test8: Format 2 7-bit 106 PRB),
- (Test9: Format 2 8-bit 106 PRB),
- (Test10: Format 2 9-bit 106 PRB),
- (Test11: Format 2 10-bit 106 PRB),
- (Test12: Format 2 11-bit 106 PRB)
+ (Test4: Format 2 3-bit 2/106 PRB),
+ (Test5: Format 2 4-bit 2/106 PRB),
+ (Test6: Format 2 5-bit 2/106 PRB),
+ (Test7: Format 2 6-bit 2/106 PRB),
+ (Test8: Format 2 7-bit 2/106 PRB),
+ (Test9: Format 2 8-bit 2/106 PRB),
+ (Test10: Format 2 9-bit 2/106 PRB),
+ (Test11: Format 2 10-bit 2/106 PRB),
+ (Test12: Format 2 11-bit 2/106 PRB),
+ (Test13: Format 2 12-bit 8/106 PRB),
+ (Test14: Format 2 19-bit 8/106 PRB),
+ (Test15: Format 2 32-bit 8/106 PRB),
+ (Test16: Format 2 32-bit 16/106 PRB),
+ (Test17: Format 2 64-bit 16/106 PRB)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1206,8 +1215,14 @@
-R 106 -i 1 -P 2 -b 9 -s5 -n1000
-R 106 -i 1 -P 2 -b 10 -s6 -n1000
-R 106 -i 1 -P 2 -b 11 -s6 -n1000
+ -R 106 -i 1 -P 2 -q8 -b 12 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q8 -b 19 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q8 -b 19 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q8 -b 32 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q16 -b 32 -s-3 -n1000
+ -R 106 -i 1 -P 2 -q16 -b 64 -s-3 -n1000
- nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4 nr_pucchsim.test5 nr_pucchsim.test6 nr_pucchsim.test7 nr_pucchsim.test8 nr_pucchsim.test9 nr_pucchsim.test10 nr_pucchsim.test11 nr_pucchsim.test12
+ nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4 nr_pucchsim.test5 nr_pucchsim.test6 nr_pucchsim.test7 nr_pucchsim.test8 nr_pucchsim.test9 nr_pucchsim.test10 nr_pucchsim.test11 nr_pucchsim.test12 nr_pucchsim.test13 nr_pucchsim.test14 nr_pucchsim.test15 nr_pucchsim.test16 nr_pucchsim.test17
PUCCH test OK
segmentation fault|assertion|exiting|fatal
3
@@ -1275,6 +1290,26 @@
3
+
+ execution
+ nr_prachsim Test cases. (Test1: 106 PRBs),
+ (Test2: 217 PRBs),
+ (Test3: 273 PRBs)
+
+ $OPENAIR_DIR/cmake_targets/build_oai
+ --phy_simulators -c
+ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash
+
+ $OPENAIR_DIR/targets/bin/nr_prachsim.Rel15
+ -a -s -30 -n 100 -p 16 -R 106
+ -a -s -30 -n 100 -p 16 -R 217
+ -a -s -30 -n 100 -p 16 -R 273
+ nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3
+ PRACH test OK
+ segmentation fault|assertion|exiting|fatal
+ 3
+
+
lte-softmodem
diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index 2d861f2dc3..2e9fd614c5 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -179,8 +179,8 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
*(cfgoptions[i].u64ptr) = (uint64_t)llu;
printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].u64ptr)) );
} else {
- *(cfgoptions[i].iptr) = llu;
- printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].i64ptr)) );
+ *(cfgoptions[i].i64ptr) = llu;
+ printf_params("[LIBCONFIG] %s: %lld\n", cfgpath,(long long)(*(cfgoptions[i].i64ptr)) );
}
} else {
defval=config_setdefault_int64(&(cfgoptions[i]),prefix);
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 8a236c49f9..5f07fc00aa 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -52,6 +52,7 @@ int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) {
else return(N_RB-1-tmp2);
}
+/* TS 38.214 ch. 6.1.2.2.2 - Resource allocation type 1 for DL and UL */
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) {
AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d) for BWPsize %d\n",NPRB,RBstart,BWPsize);
@@ -62,14 +63,21 @@ int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) {
int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) {
return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275));
}
+
/// Target code rate tables indexed by Imcs
+/* TS 38.214 table 5.1.3.1-1 - MCS index table 1 for PDSCH */
uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
- // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
+
+/* TS 38.214 table 5.1.3.1-2 - MCS index table 2 for PDSCH */
+// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
+
+/* TS 38.214 table 5.1.3.1-3 - MCS index table 3 for PDSCH */
uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
+
uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \
336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \
1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 0cd25ee231..9e27ecf358 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -256,6 +256,7 @@ typedef struct IttiMsgText_s {
//#include
#include
+#include
void *rrc_enb_process_itti_msg(void *);
#include
#include
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index a539b030e4..41ed3c77e7 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -309,7 +309,6 @@ The following features are valid for the gNB and the 5G-NR UE.
- ACK / NACK handling and HARQ procedures for downlink
- **As of May 2020** only DL was validated with COTS phone ; UL in progress, validated with OAI UE in noS1 mode
-
# OpenAirInterface 5G-NR UE Feature Set #
**as of May 2020** only supporting "noS1" mode (DL):
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 0c66b58547..37eadd92f3 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -56,9 +56,56 @@ oai supports [number of deployment](FEATURE_SET.md) model, the following are tes
1. [Monolithic eNodeB](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/HowToConnectCOTSUEwithOAIeNBNew) where the whole signal processing is performed in a single process
2. if4p5 mode, where frequency domain samples are carried over ethernet, from the RRU which implement part of L1(FFT,IFFT,part of PRACH), to a RAU
+# 5G NR
+
+As of February 2020, all 5G NR development is part of the develop branch (the branch develop-nr is no longer maintained). This also means that all new development will be merged into there once it passes all the CI.
+
+## NSA setup with COTS UE
+
+This setup requires an EPC, an OAI eNB and gNB, and a COTS Phone. A dedicated page describe the setup can be found [here](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home/gNB-COTS-UE-testing).
+
+### Launch gNB
+
+```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf```
+
+### Launch eNB
+
+```bash sudo ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf```
+## phy-test setup with OAI UE
+
+The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC. In this case both gNB and eNB need to be run with the --phy-test flag. At the gNB this flag does the following
+ - it reads the RRC configuration from the configuration file
+ - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw
+ - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload
+
+At the UE the --phy-test flag will
+ - read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them.
+
+
+### Launch gNB
+
+```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test```
+
+### Launch UE in another window
+
+```bash sudo ./nr-uesoftmodem --phy-test [--rrc_config_path ../../../ci-scripts/rrc-files]```
+
+Some other useful paramters of the UE are
+
+ - --ue-fo-compensation: enables the frequency offset compenstation at the UE. This is useful when running over the air and/or without an external clock/time source
+ - --usrp-args: this is the equivalend paramter of sdr_addrs field in the gNB config file and can be used to identify the USRP and set some basic paramters (like the clock source)
+ - --clock-source: sets the clock-source (internal or external).
+ - --time-source: sets the time-source (internal or external).
+
+
+## noS1 setup with OAI UE
+
+Instead of randomly generated payload, in the phy-test mode we can also inject/receive user-plane traffic over a TUN interface. This is the so-called noS1 mode.
+
+This setup is described in the [rfsimulator page](../targets/ARCH/rfsimulator/README.md#5g-case). In theory this should also work with the real hardware target although this has yet to be tested.
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index aa16c771ae..0d87720e2c 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -47,7 +47,7 @@
#include "SCHED/sched_eNB.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
-#include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
@@ -162,14 +162,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
- gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
+ gNB->UL_INFO.rach_ind.number_of_pdus ||
gNB->UL_INFO.cqi_ind.number_of_cqis
) {
- LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
+ LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
- NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
+ gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus,
gNB->UL_INFO.cqi_ind.number_of_cqis,
frame_rx, slot_rx,
frame_tx, slot_tx);
@@ -202,6 +202,13 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
// UE-specific RX processing for subframe n
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
+
+ // Do PRACH RU processing
+ int prach_id=find_nr_prach(gNB,frame_rx,slot_rx,0,SEARCH_EXIST);
+ if (prach_id>=0) {
+ L1_nr_prach_procedures(gNB,frame_rx,slot_rx,&gNB->prach_vars.list[prach_id].pdu);
+ gNB->prach_vars.list[prach_id].frame=-1;
+ }
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 3ea026f6e6..d6f7fb4374 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -51,6 +51,7 @@
#include "PHY/defs_nr_common.h"
#include "PHY/phy_extern.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/INIT/phy_init.h"
#include "SCHED/sched_eNB.h"
#include "SCHED_NR/sched_nr.h"
@@ -289,7 +290,7 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
// southbound IF4p5 fronthaul
void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
@@ -500,7 +501,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
RU_proc_t *proc = &ru->proc;
uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full=0;
@@ -697,7 +698,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
void *txp[ru->nb_tx];
unsigned int txs;
int i,txsymb;
@@ -789,7 +790,7 @@ void *ru_thread_asynch_rxtx( void *param ) {
static int ru_thread_asynch_rxtx_status;
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
int slot=0, frame=0;
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
wait_sync("ru_thread_asynch_rxtx");
@@ -1034,10 +1035,10 @@ int wakeup_prach_ru(RU_t *ru) {
void fill_rf_config(RU_t *ru, char *rf_config_file) {
int i;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index
+ nfapi_nr_config_request_scf_t *config = &ru->config; //tmp index
openair0_config_t *cfg = &ru->openair0_cfg;
- int mu = gNB_config->ssb_config.scs_common.value;
- int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
+ int mu = config->ssb_config.scs_common.value;
+ int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
if (mu == NR_MU_0) { //or if LTE
if(N_RB == 100) {
@@ -1122,7 +1123,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu);
}
- if (gNB_config->cell_config.frame_duplex_type.value==TDD)
+ if (config->cell_config.frame_duplex_type.value==TDD)
cfg->duplex_mode = duplex_mode_TDD;
else //FDD
cfg->duplex_mode = duplex_mode_FDD;
@@ -1161,7 +1162,7 @@ int setup_RU_buffers(RU_t *ru) {
int card,ant;
//uint16_t N_TA_offset = 0;
NR_DL_FRAME_PARMS *frame_parms;
- //nfapi_nr_config_request_t *gNB_config = ru->gNB_list[0]->gNB_config; //tmp index
+ nfapi_nr_config_request_scf_t *config = &ru->config;
if (ru) {
frame_parms = ru->nr_frame_parms;
@@ -1170,12 +1171,54 @@ int setup_RU_buffers(RU_t *ru) {
printf("ru pointer is NULL\n");
return(-1);
}
+ int mu = config->ssb_config.scs_common.value;
+ int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
- /* if (frame_parms->frame_type == TDD) {
- if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624;
- else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2;
- else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4;
- } */
+
+ if (config->cell_config.frame_duplex_type.value == TDD) {
+ int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
+
+ double factor=1;
+
+ switch (mu) {
+ case 0: //15 kHz scs
+ AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n");
+ if (N_RB <= 25) factor = .25; // 7.68 Ms/s
+ else if (N_RB <=50) factor = .5; // 15.36 Ms/s
+ else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
+ else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
+ else AssertFatal(1==0,"Too many PRBS for mu=0\n");
+ break;
+ case 1: //30 kHz sc
+ AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n");
+ if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
+ else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
+ break;
+ case 2: //60 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ break;
+ case 3: //120 kHz scs
+ AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n");
+ break;
+ case 4: //240 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
+ else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
+ else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
+ break;
+
+ if (N_RB == 100) ru->N_TA_offset = 624;
+ else if (N_RB == 50) ru->N_TA_offset = 624/2;
+ else if (N_RB == 25) ru->N_TA_offset = 624/4;
+ }
+ if (frame_parms->threequarter_fs == 1) factor = factor*.75;
+ ru->N_TA_offset = (int)(N_TA_offset * factor);
+ LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor,
+ config->carrier_config.uplink_frequency.value, N_RB);
+ }
+ else ru->N_TA_offset = 0;
+
+
if (ru->openair0_cfg.mmapped_dma == 1) {
// replace RX signal buffers with mmaped HW versions
for (i=0; inb_rx; i++) {
@@ -1388,7 +1431,7 @@ void *ru_thread( void *param ) {
int i = 0;
int aa;
- nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
// set default return value
ru_thread_status = 0;
@@ -1400,7 +1443,7 @@ void *ru_thread( void *param ) {
if(emulate_rf) {
fill_rf_config(ru,ru->rf_config_file);
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
+ nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
nr_phy_init_RU(ru);
@@ -1420,8 +1463,10 @@ void *ru_thread( void *param ) {
AssertFatal(ret==0,"Cannot connect to remote radio\n");
}
+ memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
+
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
+ 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);
@@ -1532,6 +1577,17 @@ void *ru_thread( void *param ) {
for (aa=0;aanb_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));
+
+ // Do PRACH RU processing
+ int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
+ if (prach_id>=0) {
+ rx_nr_prach_ru(ru,
+ ru->prach_list[prach_id].fmt,
+ ru->prach_list[prach_id].numRA,
+ ru->prach_list[prach_id].prachStartSymbol,
+ proc->frame_rx,proc->tti_rx);
+ free_nr_ru_prach_entry(ru,prach_id);
+ }
}
// At this point, all information for subframe has been received on FH interface
@@ -1903,7 +1959,7 @@ void configure_ru(int idx,
RU_t *ru = RC.ru[idx];
RRU_config_t *config = (RRU_config_t *)arg;
RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg;
- nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
int ret;
LOG_I(PHY, "Received capabilities from RRU %d\n",idx);
@@ -1926,15 +1982,15 @@ void configure_ru(int idx,
//config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S;
config->att_tx[0] = ru->att_tx;
config->att_rx[0] = ru->att_rx;
- config->N_RB_DL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
- config->N_RB_UL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
+ config->N_RB_DL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
+ config->N_RB_UL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs;
/* if (ru->if_south==REMOTE_IF4p5) {
config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
config->prach_ConfigIndex[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n",
config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);*/
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms);
+ nr_init_frame_parms(&ru->config, ru->nr_frame_parms);
nr_phy_init_RU(ru);
}
@@ -1942,23 +1998,23 @@ void configure_rru(int idx,
void *arg) {
RRU_config_t *config = (RRU_config_t *)arg;
RU_t *ru = RC.ru[idx];
- nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
+ nfapi_nr_config_request_scf_t *cfg = &ru->config;
ru->nr_frame_parms->nr_band = config->band_list[0];
ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0];
ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0];
if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) {
- gNB_config->cell_config.frame_duplex_type.value = TDD;
+ cfg->cell_config.frame_duplex_type.value = TDD;
//ru->nr_frame_parms->tdd_config = config->tdd_config[0];
//ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0];
} else
- gNB_config->cell_config.frame_duplex_type.value = FDD;
+ cfg->cell_config.frame_duplex_type.value = FDD;
ru->att_tx = config->att_tx[0];
ru->att_rx = config->att_rx[0];
- int mu = gNB_config->ssb_config.scs_common.value;
- gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0];
- gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0];
+ int mu = cfg->ssb_config.scs_common.value;
+ cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0];
+ cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0];
ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0];
//ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0];
@@ -1973,7 +2029,7 @@ void configure_rru(int idx,
}
fill_rf_config(ru,ru->rf_config_file);
- nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms);
+ nr_init_frame_parms(&ru->config, ru->nr_frame_parms);
nr_phy_init_RU(ru);
}
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index ccb3f28d98..305e4c4fc8 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -57,6 +57,7 @@
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
+#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_EXCCLK "tells hardware to use a clock reference (0:internal(default), 1:external, 2:gpsdo)\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index f473d0161b..2a9b3a0700 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -178,6 +178,7 @@ extern void reset_opp_meas(void);
extern void print_opp_meas(void);
extern void init_eNB_afterRU(void);
+extern void *udp_eNB_task(void *args_p);
int transmission_mode=1;
int emulate_rf = 0;
@@ -384,10 +385,10 @@ int create_gNB_tasks(uint32_t gnb_nb) {
if (gnb_nb > 0) {
/* Last task to create, others task must be ready before its start */
- if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
+ /*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1;
- }
+ }*/
if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
@@ -402,35 +403,39 @@ int create_gNB_tasks(uint32_t gnb_nb) {
}
}
- /*
- if (EPC_MODE_ENABLED) {
- if (gnb_nb > 0) {
- if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
- LOG_E(SCTP, "Create task for SCTP failed\n");
- return -1;
- }
+ if (EPC_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
+ if (gnb_nb > 0) {
+ /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
+ LOG_E(SCTP, "Create task for SCTP failed\n");
+ return -1;
+ }
- if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
- LOG_E(S1AP, "Create task for S1AP failed\n");
- return -1;
- }
- if(!emulate_rf){
- if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
- LOG_E(UDP_, "Create task for UDP failed\n");
- return -1;
- }
- }
+ if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
+ LOG_E(S1AP, "Create task for S1AP failed\n");
+ return -1;
+ }*/
- if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) {
- LOG_E(GTPU, "Create task for GTPV1U failed\n");
- return -1;
- }
+
+ if(!emulate_rf){
+ if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
+ LOG_E(UDP_, "Create task for UDP failed\n");
+ return -1;
}
+ }
+ if (itti_create_task (TASK_GTPV1_U, >pv1u_gNB_task, NULL) < 0) {
+ LOG_E(GTPU, "Create task for GTPV1U failed\n");
+ return -1;
+ }
}
- */
+ }
+
if (gnb_nb > 0) {
+ if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
+ LOG_E(GNB_APP, "Create task for gNB APP failed\n");
+ return -1;
+ }
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
@@ -819,6 +824,10 @@ int main( int argc, char **argv )
}
openair0_cfg[0].threequarter_fs = threequarter_fs;
+ EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
+
+ if (get_softmodem_params()->do_ra)
+ AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
#if T_TRACER
T_Config_Init();
@@ -954,7 +963,9 @@ if(!IS_SOFTMODEM_NOS1)
scopeParms_t p;
p.argc=&argc;
p.argv=argv;
- startScope(&p);
+ p.gNB=RC.gNB[0];
+ p.ru=RC.ru[0];
+ gNBinitScope(&p);
}
if (nfapi_mode != 1 && nfapi_mode != 2) {
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 761420a703..63c3172917 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -21,7 +21,7 @@
#include "executables/thread-common.h"
#include "executables/nr-uesoftmodem.h"
-#include "LAYER2/NR_MAC_UE/mac.h"
+#include "NR_MAC_UE/mac.h"
//#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
@@ -32,7 +32,7 @@
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
-#include "LAYER2/NR_MAC_UE/mac_proto.h"
+#include "NR_MAC_UE/mac_proto.h"
#include "RRC/NR_UE/rrc_proto.h"
//#ifndef NO_RAT_NR
@@ -142,15 +142,23 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
uint8_t abstraction_flag)
{
+ int nb_connected_gNB = 1, gNB_id;
+
memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
+ // Setting UE mode to NOT_SYNCHED by default
+ for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){
+ ue->UE_mode[gNB_id] = NOT_SYNCHED;
+ ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t));
+ }
+
// initialize all signal buffers
- init_nr_ue_signal(ue,1,abstraction_flag);
+ init_nr_ue_signal(ue, nb_connected_gNB, abstraction_flag);
// intialize transport
- init_nr_ue_transport(ue,abstraction_flag);
+ init_nr_ue_transport(ue, abstraction_flag);
}
/*!
@@ -358,82 +366,31 @@ static void UE_synch(void *arg) {
void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
- uint32_t rb_size, rb_start;
- uint16_t rnti, l_prime_mask, n_rb0, n_rb1, pdu_bit_map;
- uint8_t nr_of_symbols, start_symbol_index, mcs_index, mcs_table, nrOfLayers, harq_process_id, rv_index, dmrs_config_type;
- uint8_t ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, ptrs_time_density, ptrs_freq_density;
- nr_dcireq_t dcireq;
- nr_scheduled_response_t scheduled_response;
+ fapi_nr_config_request_t *cfg = &UE->nrUE_config;
+ int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx);
+ uint8_t gNB_id = 0;
- // program PUSCH. this should actually be done by the MAC upon reception of an UL DCI
- if (proc->nr_tti_tx == 8 || UE->frame_parms.frame_type == FDD){
+ if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
- dcireq.module_id = UE->Mod_id;
- dcireq.gNB_index = 0;
- dcireq.cc_id = 0;
- dcireq.frame = proc->frame_rx;
- dcireq.slot = proc->nr_tti_rx;
+ // trigger L2 to run ue_scheduler thru IF module
+ // [TODO] mapping right after NR initial sync
+ if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
+ nr_uplink_indication_t ul_indication;
+ memset((void*)&ul_indication, 0, sizeof(ul_indication));
- scheduled_response.dl_config = NULL;
- scheduled_response.ul_config = &dcireq.ul_config_req;
- scheduled_response.tx_request = NULL;
- scheduled_response.module_id = UE->Mod_id;
- scheduled_response.CC_id = 0;
- scheduled_response.frame = proc->frame_rx;
- scheduled_response.slot = proc->nr_tti_rx;
- //--------------------------Temporary configuration-----------------------------//
- rnti = 0x1234;
- rb_size = 50;
- rb_start = 0;
- nr_of_symbols = 12;
- start_symbol_index = 2;
- nrOfLayers = 1;
- mcs_index = 9;
- mcs_table = 0;
- harq_process_id = 0;
- rv_index = 0;
- l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
- dmrs_config_type = 0;
- ptrs_mcs1 = 2;
- ptrs_mcs2 = 4;
- ptrs_mcs3 = 10;
- n_rb0 = 25;
- n_rb1 = 75;
- pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
- ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
- ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
- //------------------------------------------------------------------------------//
+ ul_indication.module_id = UE->Mod_id;
+ ul_indication.gNB_index = gNB_id;
+ ul_indication.cc_id = UE->CC_id;
+ ul_indication.frame_rx = proc->frame_rx;
+ ul_indication.slot_rx = proc->nr_tti_rx;
+ ul_indication.frame_tx = proc->frame_tx;
+ ul_indication.slot_tx = proc->nr_tti_tx;
- scheduled_response.ul_config->slot = 8;
- scheduled_response.ul_config->number_pdus = 1;
- scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
-
- if (1 << ptrs_time_density >= nr_of_symbols) {
- scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+ UE->if_inst->ul_indication(&ul_indication);
}
- nr_ue_scheduled_response(&scheduled_response);
-
if (UE->mode != loop_through_memory) {
- uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx];
+ uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_rx];
phy_procedures_nrUE_TX(UE,proc,0,thread_id);
}
}
@@ -441,41 +398,26 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
- nr_dcireq_t dcireq;
- nr_scheduled_response_t scheduled_response;
- uint8_t ssb_period = UE->nrUE_config.ssb_table.ssb_period;
+ fapi_nr_config_request_t *cfg = &UE->nrUE_config;
+ int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_tti_rx);
+ uint8_t gNB_id = 0;
- //program DCI for slot 1
- //TODO: all of this has to be moved to the MAC!!!
- if (proc->nr_tti_rx == NR_DOWNLINK_SLOT || UE->frame_parms.frame_type == FDD){
- dcireq.module_id = UE->Mod_id;
- dcireq.gNB_index = 0;
- dcireq.cc_id = 0;
- dcireq.frame = proc->frame_rx;
- dcireq.slot = proc->nr_tti_rx;
- nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
+ if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){
- // we should have received a DL DCI here, so configure DL accordingly
- scheduled_response.dl_config = &dcireq.dl_config_req;
- scheduled_response.ul_config = NULL;
- scheduled_response.tx_request = NULL;
- scheduled_response.module_id = UE->Mod_id;
- scheduled_response.CC_id = 0;
- if (!((proc->frame_rx)%(1<<(ssb_period-1)))) {
- if(proc->frame_rx > dcireq.dl_config_req.sfn)
- UE->frame_gap = proc->frame_rx - dcireq.dl_config_req.sfn;
- if(proc->frame_rx < dcireq.dl_config_req.sfn)
- UE->frame_gap = dcireq.dl_config_req.sfn - proc->frame_rx;
- proc->frame_rx = dcireq.dl_config_req.sfn;
+ if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
+ nr_downlink_indication_t dl_indication;
+ memset((void*)&dl_indication, 0, sizeof(dl_indication));
+
+ dl_indication.module_id = UE->Mod_id;
+ dl_indication.gNB_index = gNB_id;
+ dl_indication.cc_id = UE->CC_id;
+ dl_indication.frame = proc->frame_rx;
+ dl_indication.slot = proc->nr_tti_rx;
+
+ UE->if_inst->dl_indication(&dl_indication, NULL);
}
- scheduled_response.frame = proc->frame_rx;
- scheduled_response.slot = proc->nr_tti_rx;
-
- nr_ue_scheduled_response(&scheduled_response);
- }
// Process Rx data for one sub-frame
- if ( proc->nr_tti_rx >=0 && proc->nr_tti_rx <= 1 ) {
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
@@ -494,22 +436,6 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
pdcp_run(&ctxt);
}
}
-
- // no UL for now
- /*
- if (UE->mac_enabled==1) {
- // trigger L2 to run ue_scheduler thru IF module
- // [TODO] mapping right after NR initial sync
- if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
- UE->ul_indication.module_id = 0;
- UE->ul_indication.gNB_index = 0;
- UE->ul_indication.cc_id = 0;
- UE->ul_indication.frame = proc->frame_rx;
- UE->ul_indication.slot = proc->nr_tti_rx;
- UE->if_inst->ul_indication(&UE->ul_indication);
- }
- }
- */
}
/*!
@@ -526,7 +452,7 @@ typedef struct processingData_s {
} processingData_t;
void UE_processing(void *arg) {
- processingData_t *rxtxD=(processingData_t *) arg;
+ processingData_t *rxtxD = (processingData_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
@@ -556,9 +482,7 @@ void UE_processing(void *arg) {
}
processSlotRX(UE, proc);
-
processSlotTX(UE, proc);
-
}
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
@@ -633,11 +557,6 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
}
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
- if (IS_SOFTMODEM_RFSIM) {
- LOG_D(PHY,"SET rx_offset %d \n",UE->rx_offset);
- //UE->rx_offset_diff=0;
- return 0;
- }
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 &&
@@ -704,8 +623,11 @@ void *UE_thread(void *arg) {
if (res) {
syncRunning=false;
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
- // shift the frame index with all the frames we trashed meanwhile we perform the synch search
- decoded_frame_rx=(tmp->proc.decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
+ if (UE->is_synchronized) {
+ decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
+ // shift the frame index with all the frames we trashed meanwhile we perform the synch search
+ decoded_frame_rx=(decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
+ }
delNotifiedFIFO_elt(res);
} else {
readFrame(UE, ×tamp, true);
@@ -750,6 +672,7 @@ void *UE_thread(void *arg) {
absolute_slot++;
+
// whatever means thread_idx
// Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
// Slot 3 will overlap if RX_NB_TH is 2
@@ -762,13 +685,13 @@ void *UE_thread(void *arg) {
curMsg->UE=UE;
// update thread index for received subframe
curMsg->UE->current_thread_id[slot_nr] = thread_idx;
- curMsg->proc.CC_id = 0;
+ curMsg->proc.CC_id = UE->CC_id;
curMsg->proc.nr_tti_rx= slot_nr;
curMsg->proc.subframe_rx=slot_nr/(nb_slot_frame/10);
curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx;
- curMsg->proc.frame_rx = ((absolute_slot/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
- curMsg->proc.frame_tx = (((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
+ curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER;
+ curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg->proc.decoded_frame_rx=-1;
//LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB);
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 9b2b704833..b96f98e1f2 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -71,41 +71,16 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "PHY/INIT/phy_init.h"
#include "system.h"
#include
-#include
-#include
+#include "NR_MAC_UE/mac_defs.h"
+#include "NR_MAC_UE/mac_proto.h"
#include
#include
-#include
-
-
-/* Callbacks, globals and object handlers */
-
-extern void reset_stats( FL_OBJECT *, long );
-//extern void initTpool(char *params, tpool_t *pool, bool performanceMeas);
-
-/* Forms and Objects */
-
-typedef struct {
- FL_FORM *stats_form;
- void *vdata;
- char *cdata;
- long ldata;
- FL_OBJECT *stats_text;
- FL_OBJECT *stats_button;
-} FD_stats_form;
-
-extern FD_stats_form *create_form_stats_form( void );
-
-#include "PHY/TOOLS/nr_phy_scope.h"
//#include "stats.h"
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
+#include "PHY/TOOLS/nr_phy_scope.h"
// at eNB 0, an UL scope for every UE
-FD_phy_scope_nrue *form_nrue[NUMBER_OF_UE_MAX];
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
-char title[255];
-static pthread_t forms_thread; //xforms
#include
#include "executables/softmodem-common.h"
@@ -304,35 +279,6 @@ void reset_stats(FL_OBJECT *button, long arg) {
}*/
}
-static void *scope_thread(void *arg) {
- sleep(5);
-
- while (!oai_exit) {
- phy_scope_nrUE(form_nrue[0],
- PHY_vars_UE_g[0][0],
- 0,0,1);
- usleep(100*1000);
- }
-
- pthread_exit((void *)arg);
-}
-
-
-void init_scope(void) {
- int fl_argc=1;
-
- if (do_forms==1) {
- char *name="5G-UE-scope";
- fl_initialize (&fl_argc, &name, NULL, 0, 0);
- int UE_id = 0;
- form_nrue[UE_id] = create_phy_scope_nrue();
- sprintf (title, "NR DL SCOPE UE");
- fl_show_form (form_nrue[UE_id]->phy_scope_nrue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
- threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
- }
-
-}
-
void *l2l1_task(void *arg) {
MessageDef *message_p = NULL;
int result;
@@ -720,6 +666,9 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **));
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
+ if (get_softmodem_params()->do_ra)
+ AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
+
for (int CC_id=0; CC_idofdm_symbol_size);
frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx;
@@ -746,11 +695,6 @@ int main( int argc, char **argv ) {
init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag);
- if (get_softmodem_params()->phy_test==1)
- UE[CC_id]->mac_enabled = 0;
- else
- UE[CC_id]->mac_enabled = 1;
-
UE[CC_id]->mac_enabled = 1;
UE[CC_id]->if_inst = nr_ue_if_module_init(0);
UE[CC_id]->UE_scan = UE_scan;
@@ -763,15 +707,49 @@ int main( int argc, char **argv ) {
UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
- if (frame_parms[CC_id]->frame_type==FDD) {
+ if (UE[CC_id]->frame_parms.frame_type == FDD) {
UE[CC_id]->N_TA_offset = 0;
} else {
- if (frame_parms[CC_id]->N_RB_DL == 100)
- UE[CC_id]->N_TA_offset = 624;
- else if (frame_parms[CC_id]->N_RB_DL == 50)
- UE[CC_id]->N_TA_offset = 624/2;
- else if (frame_parms[CC_id]->N_RB_DL == 25)
- UE[CC_id]->N_TA_offset = 624/4;
+ int N_RB = UE[CC_id]->frame_parms.N_RB_DL;
+ int N_TA_offset = UE[CC_id]->frame_parms.ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
+ double factor=1;
+ switch (UE[CC_id]->frame_parms.numerology_index) {
+ case 0: //15 kHz scs
+ AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
+ if (N_RB <= 25) factor = .25; // 7.68 Ms/s
+ else if (N_RB <=50) factor = .5; // 15.36 Ms/s
+ else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
+ else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
+ else AssertFatal(1==0,"Too many PRBS for mu=0\n");
+ break;
+ case 1: //30 kHz sc
+ AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
+ if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
+ else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
+ break;
+ case 2: //60 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ break;
+ case 3: //120 kHz scs
+ AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
+ break;
+ case 4: //240 kHz scs
+ AssertFatal(1==0,"scs_common should not be 60 kHz\n");
+ if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
+ else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
+ else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
+ break;
+
+ if (N_RB == 100)
+ UE[CC_id]->N_TA_offset = 624;
+ else if (N_RB == 50)
+ UE[CC_id]->N_TA_offset = 624/2;
+ else if (N_RB == 25)
+ UE[CC_id]->N_TA_offset = 624/4;
+ }
+ if (UE[CC_id]->frame_parms.threequarter_fs == 1) factor = factor*.75;
+ UE[CC_id]->N_TA_offset = (int)(N_TA_offset * factor);
+ LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", UE[CC_id]->Mod_id, UE[CC_id]->N_TA_offset, factor, UE[CC_id]->frame_parms.ul_CarrierFreq, N_RB);
}
}
@@ -782,7 +760,8 @@ int main( int argc, char **argv ) {
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
configure_linux();
mlockall(MCL_CURRENT | MCL_FUTURE);
- init_scope();
+ if (do_forms)
+ nrUEinitScope(PHY_vars_UE_g[0][0]);
number_of_cards = 1;
for(int CC_id=0; CC_id
#include "PHY/defs_nr_UE.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
-#include
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index 0ac7b6449e..449d2e0957 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -55,6 +55,7 @@ extern "C"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
+#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n"
#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0"
#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
@@ -97,6 +98,7 @@ extern "C"
#define SPLIT73 softmodem_params.split73
#define TP_CONFIG softmodem_params.threadPoolConfig
#define PHY_TEST softmodem_params.phy_test
+#define DO_RA softmodem_params.do_ra
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
#define CHAIN_OFFSET softmodem_params.chain_offset
@@ -114,6 +116,7 @@ extern "C"
{"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:(char **)&TP_CONFIG, defstrval:"n", TYPE_STRING, sizeof(TP_CONFIG)}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
+ {"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \
@@ -205,6 +208,7 @@ typedef struct {
char split73[1024];
char threadPoolConfig[1024];
int phy_test;
+ int do_ra;
uint8_t usim_test;
int emulate_rf;
int wait_for_sync; //eNodeB only
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
index cbcd26c3e3..e1d06335f5 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
@@ -18,6 +18,7 @@
#define FAPI_NR_RX_PDU_TYPE_SIB 0x02
#define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03
#define FAPI_NR_DCI_IND 0x04
+#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
#define FAPI_NR_SIBS_MASK_SIB1 0x1
@@ -42,6 +43,7 @@
#define FAPI_NR_DL_CONFIG_TYPE_DCI 0x01
#define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
+#define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 2c3809f5d4..246ab13e86 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -62,7 +62,7 @@ typedef struct {
uint8_t CoreSetType;
uint8_t precoder_granularity;
uint16_t pdcch_dmrs_scrambling_id;
-
+ uint16_t scrambling_rnti;
uint8_t tci_state_pdcch;
uint8_t tci_present_in_dci;
} fapi_nr_coreset_t;
@@ -158,22 +158,29 @@ typedef struct {
fapi_nr_tx_request_body_t *tx_request_body;
} fapi_nr_tx_request_t;
- typedef struct {
- uint8_t preamble_index;
- uint8_t prach_configuration_index;
- uint16_t preamble_length;
- uint8_t power_ramping_step;
- uint16_t preamble_received_target_power;
- uint8_t msg1_fdm;
- uint8_t msg1_frequency_start;
- uint8_t zero_correlation_zone_config;
- uint8_t subcarrier_spacing;
- uint8_t restrictedset_config;
- uint16_t root_sequence_index;
- uint16_t rsrp_threshold_ssb;
- uint16_t rsrp_threshold_sul;
- uint16_t prach_freq_offset;
- } fapi_nr_ul_config_prach_pdu;
+/// This struct replaces:
+/// PRACH-ConfigInfo from 38.331 RRC spec
+/// PRACH-ConfigSIB or PRACH-Config
+typedef struct {
+ /// PHY cell ID
+ uint16_t phys_cell_id;
+ /// Num PRACH occasions
+ uint8_t num_prach_ocas;
+ /// PRACH format
+ uint8_t prach_format;
+ /// Num RA
+ uint8_t num_ra;
+ uint8_t prach_start_symbol;
+ /// 38.211 (NCS 38.211 6.3.3.1).
+ uint16_t num_cs;
+ /// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2).
+ uint16_t root_seq_id;
+ /// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set.
+ uint8_t restricted_set;
+ /// see TS 38.211 (6.3.3.2).
+ uint16_t freq_msg1;
+ // nfapi_nr_ul_beamforming_t beamforming;
+} fapi_nr_ul_config_prach_pdu;
typedef struct {
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index 54b592202d..489a4535d4 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -86,7 +86,7 @@ typedef enum {
NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86,
NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87,
NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88,
- NFAPI_NR_PHY_MSG_TYPE_PACH_INDICATION= 0X89
+ NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89
//RESERVED 0X8a ~ 0xff
} nfapi_nr_phy_msg_type_e;
@@ -623,22 +623,35 @@ typedef struct {
//table 3-37
-#define DCI_PAYLOAD_BTYE_LEN 12 //? TS38.212 sec 7.3.1
+#define DCI_PAYLOAD_BYTE_LEN 8 // 12 ? TS38.212 sec 7.3.1
+#define MAX_DCI_CORESET 8
-typedef struct
-{
- uint16_t rnti;//
- uint16_t scrambling_id;//
- uint16_t scrambling_rnti;/* */
- uint8_t cce_index;//
- uint8_t aggregation_level;//
- nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list;
- //tx power info
- uint8_t beta_pdcch_1_0;/*PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of
-SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */
- uint8_t power_control_offset_ss;//PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB
- uint16_t payload_size_bits;//The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0-> DCI_PAYLOAD_BTYE_LEN*8
- uint8_t payload[DCI_PAYLOAD_BTYE_LEN];//DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
+typedef struct {
+ // The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
+ uint16_t RNTI[MAX_DCI_CORESET];
+ // For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured,
+ // otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
+ uint16_t ScramblingId[MAX_DCI_CORESET];
+ // For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI.
+ // Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
+ uint16_t ScramblingRNTI[MAX_DCI_CORESET];
+ // CCE start Index used to send the DCI Value: 0->135
+ uint8_t CceIndex[MAX_DCI_CORESET];
+ // Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
+ uint8_t AggregationLevel[MAX_DCI_CORESET];
+ // Precoding and Beamforming structure See Table 3-43
+ nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET];
+ // PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI.
+ // This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1]
+ // Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
+ uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET];
+ // PDCCH power value used for all other PDCCH Formats.
+ // This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
+ uint8_t powerControlOffsetSS[MAX_DCI_CORESET];
+ // The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8
+ uint16_t PayloadSizeBits[MAX_DCI_CORESET];
+ // DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
+ uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN];
} nfapi_nr_dl_dci_pdu_t;
@@ -653,9 +666,6 @@ typedef struct {
uint16_t *beamIdx[275];
} nr_beamforming_t;
-#define MAX_DCI_CORESET 8
-#define DCI_PAYLOAD_BYTE_LEN 8
-
typedef struct {
///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275
uint16_t BWPSize;
@@ -685,26 +695,8 @@ typedef struct {
uint8_t precoderGranularity;
///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot
uint16_t numDlDci;
- ///The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
- uint16_t RNTI[MAX_DCI_CORESET];
- ///For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
- uint16_t ScramblingId[MAX_DCI_CORESET];
- ///For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
- uint16_t ScramblingRNTI[MAX_DCI_CORESET];
- ///CCE start Index used to send the DCI Value: 0->135
- uint8_t CceIndex[MAX_DCI_CORESET];
- ///Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
- uint8_t AggregationLevel[MAX_DCI_CORESET];
- ///Precoding and Beamforming structure See Table 3-43
- nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET];
- ///PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
- uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET];
- ///PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
- uint8_t powerControlOffsetSS[MAX_DCI_CORESET];
-///The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BTYE_LEN*8
- uint16_t PayloadSizeBits[MAX_DCI_CORESET];
- ///DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
- uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN];
+ ///DL DCI PDU
+ nfapi_nr_dl_dci_pdu_t dci_pdu;
} nfapi_nr_dl_tti_pdcch_pdu_rel15_t;
typedef struct {
@@ -1037,10 +1029,12 @@ typedef struct
{
uint16_t phys_cell_id;
uint8_t num_prach_ocas;
+ // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
+ // We added 9 = A1/B1 10 = A2/B2 11 A3/B3
uint8_t prach_format;
uint8_t num_ra;
uint8_t prach_start_symbol;
- uint16_t num_cs;//
+ uint16_t num_cs;
nfapi_nr_ul_beamforming_t beamforming;
} nfapi_nr_prach_pdu_t;
@@ -1498,7 +1492,7 @@ typedef struct
//for dci_pusch_pdu
typedef struct
{
- uint8_t pdu_bit_map;
+ uint8_t pduBitmap;
uint32_t handle;
uint16_t rnti;
uint8_t ul_cqi;
@@ -1513,7 +1507,7 @@ typedef struct
//for PUCCH PDU Format 0/1
typedef struct
{
- uint8_t pdu_bit_map;
+ uint8_t pduBitmap;
uint32_t handle;
uint16_t rnti;
uint8_t pucch_format;//PUCCH format Value: 0 -> 1 0: PUCCH Format0 1: PUCCH Format1
@@ -1529,7 +1523,7 @@ typedef struct
//PUCCH PDU Format 2/3/4
typedef struct
{
- uint8_t pdu_bit_map;
+ uint8_t pduBitmap;
uint32_t handle;
uint16_t rnti;
uint8_t pucch_format;//PUCCH format Value: 0 -> 2 0: PUCCH Format2 1: PUCCH Format3 2: PUCCH Format4
diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c
index 806d8de28c..d9adf3e24f 100644
--- a/openair1/PHY/CODING/TESTBENCH/polartest.c
+++ b/openair1/PHY/CODING/TESTBENCH/polartest.c
@@ -12,7 +12,6 @@
#include "PHY/CODING/coding_defs.h"
#include "SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
-//#include "PHY/NR_TRANSPORT/nr_transport.h"
//#include "common/utils/LOG/log.h"
//#define DEBUG_DCI_POLAR_PARAMS
@@ -27,7 +26,7 @@ int main(int argc, char *argv[])
{
//Default simulation values (Aim for iterations = 1000000.)
int decoder_int16=0;
- int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
+ int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, 2=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
double SNR, SNR_lin;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
@@ -42,6 +41,7 @@ int main(int argc, char *argv[])
switch (arguments) {
case 's':
SNRstart = atof(optarg);
+ SNRstop = SNRstart + 2;
break;
case 'd':
@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
case 'k':
testLength=atoi(optarg);
- if (testLength < 12 || testLength > 60) {
+ if (testLength < 12 || testLength > 127) {
printf("Illegal packet bitlength %d \n",testLength);
exit(-1);
}
@@ -120,12 +120,13 @@ int main(int argc, char *argv[])
crcTableInit();
if (polarMessageType == 0) { //PBCH
- aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
+ aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
} else if (polarMessageType == 1) { //DCI
- coderLength = 108*aggregation_level;
- } else if (polarMessageType == -1) { //UCI
- printf("UCI testing not supported yet\n");
- exit(-1);
+ coderLength = 108*aggregation_level;
+ } else if (polarMessageType == 2) { //UCI
+ //pucch2 parameters, 1 symbol, aggregation_level = NPRB
+ AssertFatal(aggregation_level>2,"For UCI formats, aggregation (N_RB) should be > 2\n");
+ coderLength = 16*aggregation_level;
}
//Logging
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 9b111309cd..7f466c7097 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -382,12 +382,24 @@ unsigned int crc16 (unsigned char * inptr, int bitlen);
@param bitlen length of inputs in bits*/
unsigned int crc12 (unsigned char * inptr, int bitlen);
+/*!\fn uint32_t crc12(uint8_t *inPtr, int32_t bitlen)
+\brief This computes an 11-bit crc based on 3GPP NR specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits*/
+unsigned int crc11 (unsigned char * inptr, int bitlen);
+
/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 8-bit crc based on 3GPP UMTS specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits*/
unsigned int crc8 (unsigned char * inptr, int bitlen);
+/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen)
+\brief This computes a 6-bit crc based on 3GPP NR specifications.
+@param inPtr Pointer to input byte stream
+@param bitlen length of inputs in bits*/
+unsigned int crc6 (unsigned char * inptr, int bitlen);
+
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type);
/*!\fn void phy_viterbi_dot11_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n,int offset,int traceback)
@@ -463,6 +475,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
+ uint8_t tb_scaling,
uint8_t Nl);
uint32_t nr_compute_tbslbrm(uint16_t table,
diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c
index ee5c302adb..0769ab992a 100644
--- a/openair1/PHY/CODING/crc_byte.c
+++ b/openair1/PHY/CODING/crc_byte.c
@@ -90,7 +90,9 @@ static unsigned int crc24bTable[256];
static unsigned int crc24cTable[256];
static unsigned short crc16Table[256];
static unsigned short crc12Table[256];
+static unsigned short crc11Table[256];
static unsigned char crc8Table[256];
+static unsigned char crc6Table[256];
void crcTableInit (void)
{
@@ -102,7 +104,9 @@ void crcTableInit (void)
crc24cTable[c] = crcbit (&c, 1, poly24c);
crc16Table[c] = (unsigned short) (crcbit (&c, 1, poly16) >> 16);
crc12Table[c] = (unsigned short) (crcbit (&c, 1, poly12) >> 16);
+ crc11Table[c] = (unsigned short) (crcbit (&c, 1, poly11) >> 16);
crc8Table[c] = (unsigned char) (crcbit (&c, 1, poly8) >> 24);
+ crc6Table[c] = (unsigned char) (crcbit (&c, 1, poly6) >> 24);
} while (++c);
}
@@ -207,6 +211,24 @@ crc12 (unsigned char * inptr, int bitlen)
return crc;
}
+unsigned int
+crc11 (unsigned char * inptr, int bitlen)
+{
+ int octetlen, resbit;
+ unsigned int crc = 0;
+ octetlen = bitlen / 8; /* Change in octets */
+ resbit = (bitlen % 8);
+
+ while (octetlen-- > 0) {
+ crc = (crc << 8) ^ (crc11Table[(*inptr++) ^ (crc >> 24)] << 16);
+ }
+
+ if (resbit > 0)
+ crc = (crc << resbit) ^ (crc11Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
+
+ return crc;
+}
+
unsigned int
crc8 (unsigned char * inptr, int bitlen)
{
@@ -225,6 +247,24 @@ crc8 (unsigned char * inptr, int bitlen)
return crc;
}
+unsigned int
+crc6 (unsigned char * inptr, int bitlen)
+{
+ int octetlen, resbit;
+ unsigned int crc = 0;
+ octetlen = bitlen / 8; /* Change in octets */
+ resbit = (bitlen % 8);
+
+ while (octetlen-- > 0) {
+ crc = crc6Table[(*inptr++) ^ (crc >> 24)] << 24;
+ }
+
+ if (resbit > 0)
+ crc = (crc << resbit) ^ (crc8Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24);
+
+ return crc;
+}
+
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
{
uint32_t crc=0,oldcrc=0;
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
index 53119a1c2b..18db8a01fb 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
@@ -569,7 +569,7 @@ int8_t polar_decoder_dci(double *input,
}
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
- AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
+ AssertFatal(polarParams->K > 17, "K = %d < 18, is not allowed\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
int bit_i,ip,ipmod64;
int numbytes = polarParams->K>>3;
@@ -670,7 +670,9 @@ uint32_t polar_decoder_int16(int16_t *input,
A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
- crc = (uint64_t)(crc24c(A32_flip,8*offset+len)>>8);
+ if (crclen == 24) crc = (uint64_t)((crc24c(A32_flip,8*offset+len)>>8)&0xffffff);
+ else if (crclen == 11) crc = (uint64_t)((crc11(A32_flip,8*offset+len)>>21)&0x7ff);
+ else if (crclen == 6) crc = (uint64_t)((crc6(A32_flip,8*offset+len)>>26)&0x3f);
} else if (len<=64) {
Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));;
uint8_t A64_flip[8+offset];
@@ -688,7 +690,9 @@ uint32_t polar_decoder_int16(int16_t *input,
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
- crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8);
+ if (crclen==24) crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8)&0xffffff;
+ else if (crclen==11) crc = (uint64_t)(crc11(A64_flip,8*offset+len)>>21)&0x7ff;
+ else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f;
}
#if 0
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
index 8e4b45f744..70791302cc 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
@@ -295,8 +295,8 @@ static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,vo
void build_polar_tables(t_nrPolar_params *polarParams) {
// build table b -> c'
- AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
- AssertFatal(polarParams->K < 129, "K = %d > 64, is not supported yet\n",polarParams->K);
+ AssertFatal(polarParams->K > 17, "K = %d < 18, is not possible\n",polarParams->K);
+ AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
int bit_i,ip;
int numbytes = polarParams->K>>3;
int residue = polarParams->K&7;
@@ -327,7 +327,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
AssertFatal(polarParams->N==512 || polarParams->N==256 || polarParams->N==128,"N = %d, not done yet\n",polarParams->N);
// build G bit vectors for information bit positions and convert the bit as bytes tables in nr_polar_kronecker_power_matrices.c to 64 bit packed vectors.
// keep only rows of G which correspond to information/crc bits
- polarParams->G_N_tab = (uint64_t **)malloc(polarParams->K * sizeof(int64_t *));
+ polarParams->G_N_tab = (uint64_t **)malloc((polarParams->K + polarParams->n_pc) * sizeof(int64_t *));
int k=0;
for (int i=0; iN; i++) {
@@ -412,14 +412,14 @@ void polar_encoder_fast(uint64_t *A,
int32_t crcmask,
uint8_t ones_flag,
t_nrPolar_params *polarParams) {
- AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
+ // AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->payloadBits < 65, "payload bits = %d > 64, is not supported yet\n",polarParams->payloadBits);
uint64_t B[4]= {0,0,0,0},Cprime[4]= {0,0,0,0};
int bitlen = polarParams->payloadBits;
// append crc
AssertFatal(bitlen<129,"support for payloads <= 128 bits\n");
- AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
+ // AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen;
uint64_t tcrc=0;
uint8_t offset = 0;
@@ -444,7 +444,9 @@ void polar_encoder_fast(uint64_t *A,
A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
- tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)));
+ if (polarParams->crcParityBits == 24) tcrc = (uint64_t)(((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)))&0xffffff);
+ else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)(((crcmask^(crc11(A32_flip,bitlen)>>21)))&0x7ff);
+ else if (polarParams->crcParityBits == 6) tcrc = (uint64_t)(((crcmask^(crc6(A32_flip,bitlen)>>26)))&0x3f);
} else if (bitlen<=64) {
uint8_t A64_flip[8+offset];
if (ones_flag) {
@@ -461,7 +463,8 @@ void polar_encoder_fast(uint64_t *A,
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
- tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)));
+ if (polarParams->crcParityBits == 24) tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)))&0xffffff;
+ else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)((crcmask^(crc11(A64_flip,bitlen)>>21)))&0x7ff;
}
else if (bitlen<=128) {
uint8_t A128_flip[16+offset];
@@ -479,7 +482,8 @@ void polar_encoder_fast(uint64_t *A,
A128_flip[10+offset]=((uint8_t*)&Aprime)[5]; A128_flip[11+offset]=((uint8_t*)&Aprime)[4];
A128_flip[12+offset]=((uint8_t*)&Aprime)[3]; A128_flip[13+offset]=((uint8_t*)&Aprime)[2];
A128_flip[14+offset]=((uint8_t*)&Aprime)[1]; A128_flip[15+offset]=((uint8_t*)&Aprime)[0];
- tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)));
+ if (polarParams->crcParityBits == 24) tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)))&0xffffff;
+ else if (polarParams->crcParityBits == 11) tcrc = (uint64_t)((crcmask^(crc11(A128_flip,bitlen)>>21)))&0x7ff;
}
int n;
@@ -522,6 +526,7 @@ void polar_encoder_fast(uint64_t *A,
#ifdef DEBUG_POLAR_ENCODER
+ printf("Polar encoder: (N,K) : (%d,%d)\n",polarParams->N,polarParams->K);
if (polarParams->K<65)
printf("A %llx B %llx Cprime %llx (payload bits %d,crc %x)\n",
(unsigned long long)(A[0]&(((uint64_t)1<>8);
}
-#endif
+ #endif
/* printf("Bbytes : %x.%x.%x.%x.%x.%x.%x.%x\n",Bbyte[0],Bbyte[1],Bbyte[2],Bbyte[3],Bbyte[4],Bbyte[5],Bbyte[6],Bbyte[7]);
printf("%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx\n",polarParams->cprime_tab[0][Bbyte[0]] ,
polarParams->cprime_tab[1][Bbyte[1]] ,
diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
index 42051eb1b5..1ab664e5a2 100644
--- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
+++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h
@@ -33,8 +33,8 @@
#ifndef __NR_POLAR_UCI_DEFS__H__
#define __NR_POLAR_UCI_DEFS__H__
-#define NR_POLAR_UCI_MESSAGE_TYPE -1 //int8_t
-#define NR_POLAR_UCI_CRC_ERROR_CORRECTION_BITS 3
+#define NR_POLAR_UCI_PUCCH_MESSAGE_TYPE 2 //int8_t
+#define NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS 3
#define NR_POLAR_PUCCH_PAYLOAD_BITS 32
#define NR_POLAR_PUCCH_E 32
diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c
index f6a06b3f7f..f6a700117d 100644
--- a/openair1/PHY/CODING/nr_polar_init.c
+++ b/openair1/PHY/CODING/nr_polar_init.c
@@ -43,11 +43,12 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
uint8_t aggregation_level,
int decoder_flag) {
t_nrPolar_params *currentPtr = *polarParams;
- uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
+ uint16_t aggregation_prime = (messageType >= 2) ? aggregation_level : nr_polar_aggregation_prime(aggregation_level);
//Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) {
//printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
+ //LOG_D(PHY,"Looking for index %d\n",(messageType * messageLength * aggregation_prime));
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
else currentPtr = currentPtr->nextPtr;
}
@@ -55,8 +56,9 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list.
t_nrPolar_params *newPolarInitNode = calloc(sizeof(t_nrPolar_params),1);
-
+
if (newPolarInitNode != NULL) {
+ // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime);
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL;
//printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
@@ -87,15 +89,44 @@ static void nr_polar_init(t_nrPolar_params * *polarParams,
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
//printf("Initializing polar parameters for DCI (K %d, E %d, L %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength,aggregation_level);
- } else if (messageType == -1) { //UCI
+ } else if (messageType == 2) { //UCI PUCCH2
+ AssertFatal(aggregation_level>2,"Aggregation level (%d) for PUCCH 2 encoding is NPRB and should be > 2\n",aggregation_level);
+ AssertFatal(messageLength>11,"Message length %d is too short for polar encoding of UCI\n",messageLength);
+ newPolarInitNode->n_max = NR_POLAR_PUCCH_N_MAX;
+ newPolarInitNode->i_il = NR_POLAR_PUCCH_I_IL;
+ newPolarInitNode->encoderLength = aggregation_level * 16;
+
+ newPolarInitNode->i_seg = 0;
+
+ if ((messageLength >= 360 && newPolarInitNode->encoderLength >= 1088)||
+ (messageLength >= 1013)) newPolarInitNode->i_seg = 1;
+
+ newPolarInitNode->crcParityBits = 11;
+ newPolarInitNode->n_pc = 0;
+ newPolarInitNode->n_pc_wm = 0;
+
+ if (messageLength < 20) {
+ newPolarInitNode->crcParityBits = 6;
+ newPolarInitNode->n_pc = 3;
+ if ((newPolarInitNode->encoderLength - messageLength - 6 + 3) < 193) newPolarInitNode->n_pc_wm = 1;
+ }
+
+
+
+ newPolarInitNode->i_bil = NR_POLAR_PUCCH_I_BIL;
+
+ newPolarInitNode->payloadBits = messageLength;
+ newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
+ //newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
+ //LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K,
- newPolarInitNode->encoderLength,
- newPolarInitNode->n_max);
+ newPolarInitNode->encoderLength,
+ newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
//polar_encoder vectors:
@@ -191,16 +222,19 @@ t_nrPolar_params *nr_polar_params (int8_t messageType,
nr_polar_init(polarList_ext != NULL ? polarList_ext : &polarList,
messageType,messageLength,aggregation_level,decoding_flag);
t_nrPolar_params *polarParams=polarList_ext != NULL ? *polarList_ext : polarList;
- const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level);
+ const int tag=messageType * messageLength * (messageType>=2 ? aggregation_level : nr_polar_aggregation_prime(aggregation_level));
+
+
while (polarParams != NULL) {
+ // LOG_D(PHY,"nr_polar_params : tag %d (from nr_polar_init %d)\n",tag,polarParams->idx);
if (polarParams->idx == tag)
return polarParams;
polarParams = polarParams->nextPtr;
}
- AssertFatal(false,"Polar Init tables internal failure\n");
+ AssertFatal(false,"Polar Init tables internal failure, no polarParams found\n");
return NULL;
}
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 813d419429..e544a7d0c2 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -25,7 +25,8 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
/*#include "RadioResourceConfigCommonSIB.h"
#include "RadioResourceConfigDedicated.h"
#include "TDD-Config.h"
@@ -39,7 +40,6 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "nfapi_nr_interface.h"
/*
@@ -153,11 +153,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
}
-
nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
//PUSCH DMRS init
gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(2*sizeof(uint32_t ***));
+
uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
for(int nscid=0; nscid<2; nscid++) {
@@ -232,6 +232,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
*/
prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
+ init_prach_list(gNB);
+
int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
printf("Before ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]);
@@ -405,7 +407,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
fp->nr_band = 78;
- fp->threequarter_fs= 0;
+// fp->threequarter_fs= 0;
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
@@ -417,6 +419,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
uint8_t Mod_id = phy_config->Mod_id;
+ uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion;
NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms;
nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config;
@@ -480,6 +483,14 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
return;
}
+ fd_occasion = 0;
+ nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config;
+ short_sequence = prach_config->prach_sequence_length.value;
+ num_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value;
+ rootSequenceIndex = prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value;
+
+ compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u);
+
RC.gNB[Mod_id]->configured = 1;
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index 2dcf035866..ead2538e75 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -22,6 +22,7 @@
#include "phy_init.h"
#include "SCHED/sched_common.h"
#include "PHY/phy_extern.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "SIMULATION/TOOLS/sim.h"
/*#include "RadioResourceConfigCommonSIB.h"
#include "RadioResourceConfigDedicated.h"
@@ -39,14 +40,19 @@ int nr_phy_init_RU(RU_t *ru) {
int p;
int re;
+ // For memory allocation of ru->prach_rxsigF
+ int mu = fp->numerology_index;
+
LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx);
nfapi_nr_config_request_scf_t *cfg;
ru->nb_log_antennas=0;
for (int n=0;ngNB_config;
+ cfg = &ru->config;
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
}
+ // copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration (at least the parts that are needed by the RU, numerology and PRACH)
+
AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
// Time-domain signals
@@ -107,7 +113,8 @@ int nr_phy_init_RU(RU_t *ru) {
ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; inb_rx; i++) {
- ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
+ // for preamble format 1 and 2, more memory should be allocated
+ ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*(1<rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
}
@@ -144,6 +151,8 @@ int nr_phy_init_RU(RU_t *ru) {
ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP );
+ init_prach_ru_list(ru);
+
return(0);
}
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 5a60d15e2b..1729ac0d9e 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -77,19 +77,19 @@ void phy_config_sib2_ue(uint8_t Mod_id,int CC_id,
LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,eNB_id);
- fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
+ ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
- fp->prach_config_common.prach_Config_enabled=1;
- fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
- fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag;
- fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
- fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset;
+ ue->prach_vars[eNB_id]->prach_Config_enabled=1;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
+ ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag;
+ ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset;
- compute_prach_seq(fp->prach_config_common.rootSequenceIndex,
- fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
- fp->frame_type,ue->X_u);
+ //compute_prach_seq(fp->prach_config_common.rootSequenceIndex,
+ // fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
+ // fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+ // fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
+ // fp->frame_type,ue->X_u);
@@ -226,12 +226,12 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_
LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n",
Mod_id,eNB_id);
- fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
- fp->prach_config_common.prach_Config_enabled=1;
- fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex;
- fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag;
- fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig;
- fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset;
+ ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
+ ue->prach_vars[eNB_id]->prach_Config_enabled=1;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex;
+ ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag;
+ ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig;
+ //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset;
// prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,fp->frame_type);
// N_ZC = (prach_fmt <4)?839:139;
@@ -239,12 +239,12 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_
// prach_root_sequence_map4[fp->prach_config_common.rootSequenceIndex];
//compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u);
- compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex,
- PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
- fp->frame_type,
- PHY_vars_UE_g[Mod_id][CC_id]->X_u);
+ //compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex,
+ // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
+ // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+ // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
+ // fp->frame_type,
+ // PHY_vars_UE_g[Mod_id][CC_id]->X_u);
fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift;
@@ -958,7 +958,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
// enable MIB/SIB decoding by default
ue->decode_MIB = 1;
ue->decode_SIB = 1;
- init_prach_tables(839);
+
+ init_nr_prach_tables(839);
+
return 0;
}
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
index 2fd84f563c..556a9f2d23 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
@@ -821,15 +821,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
pllr_symbol_cw0 += llr_offset_symbol;
pllr_symbol_cw1 += llr_offset_symbol;
- /*
- LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n",
+ LOG_D(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p energy: %d\n",
frame, subframe,symbol,
nb_rb,dlsch0_harq->Qm,
pdsch_vars[eNB_id]->llr_length[symbol],
pdsch_vars[eNB_id]->llr_offset[symbol],
(int16_t*)pdsch_vars[eNB_id]->llr[0],
- pllr_symbol_cw0);
- */
+ pllr_symbol_cw0,
+ signal_energy(pdsch_vars[eNB_id]->rxdataF_comp0[0], 7*2*frame_parms->N_RB_DL*12));
switch (dlsch0_harq->Qm) {
case 2 :
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 108a36a679..66f69c5d06 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -212,10 +212,10 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
}
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
- unsigned char symbol,
- unsigned char Ns,
- int sample_offset,
- int no_prefix)
+ unsigned char symbol,
+ unsigned char Ns,
+ int sample_offset,
+ int no_prefix)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
@@ -395,12 +395,13 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
int sample_offset,
int no_prefix)
{
- uint32_t slot_offset;
- uint32_t rxdata_offset;
+ int32_t slot_offset, rxdata_offset;
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+ int tmp_dft_in[8192] __attribute__ ((aligned (32)));
+
dft_size_idx_t dftsize;
switch (frame_parms->ofdm_symbol_size) {
@@ -443,14 +444,27 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
-
if(symbol == 0)
rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET;
else
rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
- dft(dftsize,(int16_t *)&rxdata[rxdata_offset],
- (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
+ if(sample_offset>rxdata_offset) {
+ memcpy((void *)tmp_dft_in,
+ (void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset],
+ (sample_offset-rxdata_offset)*sizeof(int));
+
+ memcpy((void *)&tmp_dft_in[sample_offset-rxdata_offset],
+ (void *) &rxdata[0],
+ (frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int));
+
+ dft(dftsize,(int16_t *)&tmp_dft_in,
+ (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
+ }
+ else
+ dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset],
+ (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
+
return(0);
}
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index f94a82c111..f544655197 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -116,7 +116,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//------------------generate DMRS------------------//
- nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->dmrs_config_type);
+ if (pusch_pdu->transform_precoding) // if transform precoding is disabled
+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
+ else
+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type);
//------------------------------------------------//
@@ -275,70 +278,69 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8);
- // check if PRB crosses DC and improve estimates around DC
- if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) {
- ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
- uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
- uint16_t idxPil = idxDC/2;
- re_offset = k;
- pil = (int16_t *)&pilot[0];
- pil += (idxPil-2);
- ul_ch += (idxDC-4);
- ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10);
- re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size;
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
- ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
- ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
-
- // for proper allignment of SIMD vectors
- if((gNB->frame_parms.N_RB_UL&1)==0) {
+ // check if PRB crosses DC and improve estimates around DC
+ if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) {
+ ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
+ uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
+ uint16_t idxPil = idxDC/2;
+ re_offset = k;
+ pil = (int16_t *)&pilot[0];
+ pil += (idxPil-2);
+ ul_ch += (idxDC-4);
+ ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10);
+ re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size;
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
- multadd_real_vector_complex_scalar(fdcl,
- ch,
- ul_ch-4,
- 8);
+ // for proper allignment of SIMD vectors
+ if((gNB->frame_parms.N_RB_UL&1)==0) {
+
+ multadd_real_vector_complex_scalar(fdcl,
+ ch,
+ ul_ch-4,
+ 8);
- pil += 4;
- re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
- ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
- ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+ pil += 4;
+ re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
- multadd_real_vector_complex_scalar(fdcr,
- ch,
- ul_ch-4,
- 8);
- } else {
+ multadd_real_vector_complex_scalar(fdcr,
+ ch,
+ ul_ch-4,
+ 8);
+ }
+ else {
+ multadd_real_vector_complex_scalar(fdclh,
+ ch,
+ ul_ch,
+ 8);
- multadd_real_vector_complex_scalar(fdclh,
- ch,
- ul_ch,
- 8);
+ pil += 4;
+ re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
- pil += 4;
- re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
- rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
- ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
- ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
-
- multadd_real_vector_complex_scalar(fdcrh,
- ch,
- ul_ch,
- 8);
+ multadd_real_vector_complex_scalar(fdcrh,
+ ch,
+ ul_ch,
+ 8);
+ }
}
-
- }
#ifdef DEBUG_PDSCH
- ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
- for(uint16_t idxP=0; idxPframe_parms.ofdm_symbol_size) {
+ switch (gNB->frame_parms.ofdm_symbol_size) {
case 128:
idft(IDFT_128,(int16_t*) &ul_ch_estimates[aarx][symbol_offset],
(int16_t*) ul_ch_estimates_time[aarx],
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index f933a8c7ab..4580ccce8c 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -45,7 +45,7 @@ int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}};
int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}};
int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}};
-
+// complex conjugate of mod table
short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,23170,-23170,-23170,-23170,23170};
short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170};
@@ -57,39 +57,42 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
+ uint32_t re_offset,
uint8_t dmrs_type)
{
- int8_t w;
+ int8_t w, nb_dmrs;
short *mod_table;
unsigned char idx=0;
-
+ int k;
typedef int array_of_w[2];
array_of_w *wf;
array_of_w *wt;
-
wf = (dmrs_type==pusch_dmrs_type1) ? wf1 : wf2;
wt = (dmrs_type==pusch_dmrs_type1) ? wt1 : wt2;
+ int dmrs_offset = re_offset/((dmrs_type==pusch_dmrs_type1)?2:3);
+
if (dmrs_type > 2)
- LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", dmrs_type);
+ LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type+1);
if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) {
if (gNB->frame_parms.Ncp == NORMAL) {
-
- for (int i=0; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
- ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
- ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
+ ((int16_t*)output)[k<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
+ ((int16_t*)output)[(k<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_PUSCH
- printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb);
- printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
- printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
- (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]);
+ printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb);
+ printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
+ printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
+ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[k<<1], ((int16_t*)output)[(k<<1)+1]);
#endif
+
}
} else {
LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
@@ -102,7 +105,6 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
}
-
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned int Ns,
unsigned int *nr_gold_pdsch,
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index 472d03e649..4b007f1292 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -88,6 +88,7 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
uint16_t N_n_scid[NR_MAX_NB_CODEWORDS]={Nid, Nid}; // Not correct, appropriate scrambling IDs have to be updated to support DCI 1_1
uint8_t n_scid=0; // again works only for 1_0
for (uint8_t slot=0; slotslots_per_frame; slot++) {
+
for (uint8_t symb=0; symbsymbols_per_slot; symb++) {
reset = 1;
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index d18f6405d7..1bf2ef4fb2 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -48,6 +48,7 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
unsigned short p,
unsigned char lp,
unsigned short nb_pusch_rb,
+ uint32_t re_offset,
uint8_t dmrs_type);
void init_scrambling_luts(void);
diff --git a/openair1/PHY/NR_REFSIG/scrambling_luts.c b/openair1/PHY/NR_REFSIG/scrambling_luts.c
index 9d957de0f7..790d3f7719 100644
--- a/openair1/PHY/NR_REFSIG/scrambling_luts.c
+++ b/openair1/PHY/NR_REFSIG/scrambling_luts.c
@@ -27,6 +27,7 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/sse_intrin.h"
+#include
__m64 byte2m64_re[256];
__m64 byte2m64_im[256];
@@ -42,7 +43,7 @@ void init_byte2m64(void) {
byte2m64_im[s] = _mm_insert_pi16(byte2m64_im[s],(1-2*((s>>5)&1)),2);
byte2m64_re[s] = _mm_insert_pi16(byte2m64_re[s],(1-2*((s>>6)&1)),3);
byte2m64_im[s] = _mm_insert_pi16(byte2m64_im[s],(1-2*((s>>7)&1)),3);
- printf("init_scrambling_luts: s %x (%d) ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
+ LOG_T(PHY,"init_scrambling_luts: s %x (%d) ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
((uint16_t*)&s)[0],
(1-2*(s&1)),
((int16_t*)&byte2m64_re[s])[0],((int16_t*)&byte2m64_im[s])[0],
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index d62687bd9c..8508621ae5 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -131,12 +131,13 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
void nr_pdcch_scrambling(uint32_t *in,
uint32_t size,
uint32_t Nid,
- uint32_t n_RNTI,
+ uint32_t scrambling_RNTI,
uint32_t *out) {
uint8_t reset;
uint32_t x1, x2, s=0;
reset = 1;
- x2 = (n_RNTI<<16) + Nid;
+ x2 = (scrambling_RNTI<<16) + Nid;
+ LOG_D(PHY,"PDCCH Scrambling x2 %x : scrambling_RNTI %x \n", x2, scrambling_RNTI);
for (int i=0; iCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED,
"Interleaved CCE REG MAPPING not supported\n");
uint32_t dmrs_length = (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED)?
- (n_rb*6) : (pdcch_pdu_rel15->AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
- uint32_t encoded_length = pdcch_pdu_rel15->AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE)
+ (n_rb*6) : (pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
+ uint32_t encoded_length = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType);
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
@@ -228,18 +229,19 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
/// DCI payload processing
// CRC attachment + Scrambling + Channel coding + Rate matching
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
- uint16_t n_RNTI = pdcch_pdu_rel15->RNTI[d];
- uint16_t Nid = pdcch_pdu_rel15->ScramblingId[d];
+ uint16_t n_RNTI = pdcch_pdu_rel15->dci_pdu.RNTI[d];
+ uint16_t Nid = pdcch_pdu_rel15->dci_pdu.ScramblingId[d];
+ uint16_t scrambling_RNTI = pdcch_pdu_rel15->dci_pdu.ScramblingRNTI[d];
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE,
- pdcch_pdu_rel15->PayloadSizeBits[d],
- pdcch_pdu_rel15->AggregationLevel[d],
+ pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],
+ pdcch_pdu_rel15->dci_pdu.AggregationLevel[d],
0,NULL);
- polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->Payload[d], encoder_output, n_RNTI,1,currentPtr);
+ polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d], encoder_output, n_RNTI,1,currentPtr);
#ifdef DEBUG_CHANNEL_CODING
- printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->PayloadSizeBits[d],pdcch_pdu_rel15->AggregationLevel[d]);
+ printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
- ((uint64_t*)pdcch_pdu_rel15->Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->Payload[d])[1]);
+ ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[1]);
printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
for (int i=0; i>5; i++)
@@ -249,7 +251,7 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
#endif
/// Scrambling
uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0};
- nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output);
+ nr_pdcch_scrambling(encoder_output, encoded_length, Nid, scrambling_RNTI, scrambled_output);
#ifdef DEBUG_CHANNEL_CODING
printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \
[6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n",
@@ -272,8 +274,8 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
cset_start_sc -= frame_parms.ofdm_symbol_size;
/*Reorder REG list for a freq first mapping*/
- uint8_t nb_regs = pdcch_pdu_rel15->AggregationLevel[d]*NR_NB_REG_PER_CCE;
- uint8_t reg_idx0 = pdcch_pdu_rel15->CceIndex[d]*NR_NB_REG_PER_CCE;
+ uint8_t reg_idx0 = pdcch_pdu_rel15->dci_pdu.CceIndex[d]*NR_NB_REG_PER_CCE;
+ uint8_t nb_regs = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*NR_NB_REG_PER_CCE;
/*Mapping the encoded DCI along with the DMRS */
for (int reg_idx=reg_idx0; reg_idx<(nb_regs+reg_idx0); reg_idx++) {
@@ -295,8 +297,8 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
for (int m=0; mCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) {
- ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (2*amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
- ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (2*amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
+ ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
+ ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PDCCH_DMRS
printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1],
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
index c7b14571b7..0ec835a42c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c
@@ -140,7 +140,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
int C=-1;
for (int d=0;dnumDlDci;d++) {
- int L = pdcch_pdu_rel15->AggregationLevel[d];
+ int L = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d];
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
@@ -151,10 +151,10 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
C = N_reg/(bsize*R);
}
- LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->CceIndex[d]);
+ LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu.CceIndex[d]);
for (uint8_t cce_idx=0; cce_idxcce_list[d][cce_idx];
- cce->cce_idx = pdcch_pdu_rel15->CceIndex[d] + cce_idx;
+ cce->cce_idx = pdcch_pdu_rel15->dci_pdu.CceIndex[d] + cce_idx;
LOG_D(PHY, "cce_idx %d\n", cce->cce_idx);
if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
@@ -210,12 +210,12 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
for (int i=0;inumDlDci;i++) {
- //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
+ //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
- int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
+ int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu.RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){
- LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->RNTI[i],dlsch_id);
+ LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu.RNTI[i],dlsch_id);
return;
}
@@ -228,7 +228,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
"illegal harq_pid %d\n",harq_pid);
dlsch->harq_mask |= (1<rnti = pdcch_pdu_rel15->RNTI[i];
+ dlsch->rnti = pdcch_pdu_rel15->dci_pdu.RNTI[i];
nr_fill_cce_list(gNB,0);
/*
@@ -248,7 +248,7 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
for (int i=0;inumDlDci;i++) {
- //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i];
+ //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
// if there's no DL DCI then generate CCE list
if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 4518280f6b..b8d9fdea18 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -133,13 +133,17 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
int16_t **tx_layers = (int16_t**)dlsch->txdataF;
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
-
+ uint8_t nodata_dmrs = 1;
uint8_t dmrs_Type = rel15->dmrsConfigType;
int nb_re_dmrs = (dmrs_Type== NFAPI_NR_DMRS_TYPE1) ? 6:4;
uint16_t n_dmrs = ((rel15->rbSize+rel15->rbStart)*nb_re_dmrs)<<1;
int16_t mod_dmrs[n_dmrs<<1];
- uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
+ uint16_t nb_re;
+ if (nodata_dmrs) // no data in dmrs symbol
+ nb_re = ((12*rel15->NrOfSymbols)-12-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
+ else
+ nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords;
uint8_t Qm = rel15->qamModOrder[0];
uint32_t encoded_length = nb_re*Qm;
@@ -297,15 +301,16 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
}
else {
-
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
+ if( (l != dmrs_symbol) || !nodata_dmrs) {
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
- printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
-m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
- ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
+ printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
+ m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
+ ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
- m++;
+ m++;
+ }
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
index f48905b68c..3a6851ee8f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
@@ -90,7 +90,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
-void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB);
+void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index f120864184..3aa87d656e 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -36,7 +36,7 @@
#include "PHY/CODING/coding_defs.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/CODING/nrLDPC_extern.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
@@ -49,7 +49,7 @@
//#define DEBUG_DLSCH_FREE 1
-void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB)
+void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
{
int i;
int r;
@@ -130,7 +130,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB)
}
free16(dlsch,sizeof(NR_gNB_DLSCH_t));
- dlsch = NULL;
+ *dlschptr = NULL;
}
}
@@ -335,7 +335,12 @@ int nr_dlsch_encoding(unsigned char *a,
uint32_t E;
uint8_t Ilbrm = 1;
uint32_t Tbslbrm = 950984; //max tbs
- uint8_t nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4;
+ uint8_t nodata_dmrs = 1;
+ uint8_t nb_re_dmrs;
+ if (nodata_dmrs)
+ nb_re_dmrs = 12;
+ else
+ nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4;
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
uint16_t R=rel15->targetCodeRate[0];
float Coderate = 0.0;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
index 2e6fc707bd..7702d770ee 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c
@@ -274,25 +274,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
return first_free_index;
}
-int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
- uint16_t i;
- int16_t first_free_index=-1;
-
- AssertFatal(gNB!=NULL,"gNB is null\n");
- for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i);
- AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i);
- LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index);
- if ((gNB->ulsch[i][0]->harq_mask >0) &&
- (gNB->ulsch[i][0]->rnti==rnti)) return i;
- else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
- }
- if (type == SEARCH_EXIST) return -1;
- if (first_free_index != -1)
- gNB->ulsch[first_free_index][0]->rnti = 0;
- return first_free_index;
-}
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
@@ -316,26 +298,3 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
}
-void nr_fill_ulsch(PHY_VARS_gNB *gNB,
- int frame,
- int slot,
- nfapi_nr_pusch_pdu_t *ulsch_pdu) {
-
-
- int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
- AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id);
-
- NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0];
- int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
- ulsch->rnti = ulsch_pdu->rnti;
- //ulsch->rnti_type;
- ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid;
-
- memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
-
- LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
-
-}
-
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index b6a4787193..f5a26aec80 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -32,7 +32,7 @@
*/
#include "PHY/defs_gNB.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/sse_intrin.h"
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c
index 5c4d048a77..312ad6a475 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c
@@ -31,141 +31,243 @@
*/
#include "PHY/defs_gNB.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
-#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
-extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
-extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
-extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
-extern uint16_t NCS_unrestricted_delta_f_RA_5[16];
-extern uint16_t NCS_restricted_TypeA_delta_f_RA_5[16];
-extern uint16_t NCS_restricted_TypeB_delta_f_RA_5[14];
-extern uint16_t NCS_unrestricted_delta_f_RA_15[16];
extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
-extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
-extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
-extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
+extern const char *prachfmt[9];
+
+void init_prach_list(PHY_VARS_gNB *gNB) {
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ for (int i=0; iprach_vars.list[i].frame=-1;
+}
+
+int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type) {
+
+ uint16_t i;
+ int16_t first_free_index=-1;
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ for (i=0; i %d.%d numRA %d\n", frame,slot,numRA,i,
+ gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot,gNB->prach_vars.list[i].pdu.num_ra);
+ if ((gNB->prach_vars.list[i].frame == frame) &&
+ (gNB->prach_vars.list[i].slot == slot) &&
+ (gNB->prach_vars.list[i].pdu.num_ra == numRA)) return i;
+ else if ((gNB->prach_vars.list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
+ }
+ if (type == SEARCH_EXIST) return -1;
+
+ return first_free_index;
+}
+
+void nr_fill_prach(PHY_VARS_gNB *gNB,
+ int SFN,
+ int Slot,
+ nfapi_nr_prach_pdu_t *prach_pdu) {
+
+ int prach_id = find_nr_prach(gNB,SFN,Slot,prach_pdu->num_ra,SEARCH_EXIST_OR_FREE);
+ AssertFatal( (prach_id>=0) && (prach_idnum_ra,prach_id);
+
+ gNB->prach_vars.list[prach_id].frame=SFN;
+ gNB->prach_vars.list[prach_id].slot=Slot;
+ memcpy((void*)&gNB->prach_vars.list[prach_id].pdu,(void*)prach_pdu,sizeof(*prach_pdu));
+
+}
+
+void init_prach_ru_list(RU_t *ru) {
+
+ AssertFatal(ru!=NULL,"ruis null\n");
+ for (int i=0; iprach_list[i].frame=-1;
+ pthread_mutex_init(&ru->prach_list_mutex,NULL);
+}
+
+int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) {
+
+ uint16_t i;
+ int16_t first_free_index=-1;
+
+ AssertFatal(ru!=NULL,"ru is null\n");
+ pthread_mutex_lock(&ru->prach_list_mutex);
+ for (i=0; i %d.%d\n", frame,slot,i,
+ ru->prach_list[i].frame,ru->prach_list[i].slot);
+ if ((ru->prach_list[i].frame == frame) &&
+ (ru->prach_list[i].slot == slot)) {
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+ return i;
+ }
+ else if ((ru->prach_list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
+ }
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+ if (type == SEARCH_EXIST) return -1;
+
+ return first_free_index;
+}
+
+void nr_fill_prach_ru(RU_t *ru,
+ int SFN,
+ int Slot,
+ nfapi_nr_prach_pdu_t *prach_pdu) {
+
+ int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE);
+ AssertFatal( (prach_id>=0) && (prach_idprach_list_mutex);
+ ru->prach_list[prach_id].frame = SFN;
+ ru->prach_list[prach_id].slot = Slot;
+ ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
+ ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
+ ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+
+}
+
+void free_nr_ru_prach_entry(RU_t *ru,
+ int prach_id) {
+
+ pthread_mutex_lock(&ru->prach_list_mutex);
+ ru->prach_list[prach_id].frame=-1;
+ pthread_mutex_unlock(&ru->prach_list_mutex);
+
+}
+
void rx_nr_prach_ru(RU_t *ru,
+ int prachFormat,
+ int numRA,
+ int prachStartSymbol,
int frame,
- int subframe) {
+ int slot) {
AssertFatal(ru!=NULL,"ru is null\n");
int16_t **rxsigF=NULL;
NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
- int16_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+
int16_t *prach[ru->nb_rx];
- uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
+ int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value;
+
+ int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
rxsigF = ru->prach_rxsigF;
AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n");
for (int aa=0; aanb_rx; aa++)
- prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_subframe)-ru->N_TA_offset];
-
-
+ prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot*fp->get_samples_per_slot(slot,fp))-ru->N_TA_offset];
+ int dftlen=0;
int mu = fp->numerology_index;
- int Ncp;
+ int Ncp = 0;
int16_t *prach2;
-
- switch (prach_fmt) {
- case 0:
- Ncp = 3168;
- break;
-
- case 1:
- Ncp = 21024;
- break;
-
- case 2:
- Ncp = 4688;
- break;
-
- case 3:
- Ncp = 3168;
- break;
-
- case 0xa1:
- Ncp = 288/(1<idx,frame,slot,prachFormat,msg1_frequencystart);
+ AssertFatal(prachFormat<4,"Illegal prach format %d for length 839\n",prachFormat);
+ switch (prachFormat) {
+ case 0:
+ Ncp = 3168;
+ break;
+
+ case 1:
+ Ncp = 21024;
+ break;
+
+ case 2:
+ Ncp = 4688;
+ break;
+
+ case 3:
+ Ncp = 3168;
+ break;
+
+ }
}
+ else {
+ LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n",
+ ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol);
+ switch (prachFormat) {
+ case 0: //A1
+ Ncp = 288/(1<N_RB_UL, ru->nb_rx, Ncp);
+ LOG_D(PHY,"rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d\n",ru->nb_rx, Ncp);
}
AssertFatal(mu==1,"only 30 kHz SCS handled for now\n");
// Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
int kbar = 1;
int K = 24;
- if (prach_fmt == 3) {
+ if (prach_sequence_length == 0 && prachFormat == 3) {
K=4;
kbar=10;
}
- else if (prach_fmt > 3) {
+ else if (prach_sequence_length == 1) {
// Note: Assumes that PRACH SCS is same as PUSCH SCS
K=1;
kbar=2;
}
- int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart;
+ int n_ra_prb = msg1_frequencystart;
int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
- int N_ZC = (prach_fmt<4)?839:139;
+ int N_ZC = (prach_sequence_length==0)?839:139;
if (k<0) k+=(fp->ofdm_symbol_size);
k*=K;
k+=kbar;
int reps=1;
- int dftlen=0;
for (int aa=0; aanb_rx; aa++) {
AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa);
-
// do DFT
if (fp->N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL);
@@ -173,170 +275,226 @@ void rx_nr_prach_ru(RU_t *ru,
if (fp->threequarter_fs==0) {
//40 MHz @ 61.44 Ms/s
//50 MHz @ 61.44 Ms/s
- prach2 = prach[aa] + (Ncp<<2);
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
- dft(DFT_49152,prach2,rxsigF[aa],1);
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
- reps++;
- }
- if (prach_fmt == 2) {
- dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
- dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
- reps+=2;
- }
- if (prach_fmt == 3) {
- for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
- reps=4;
- }
- if (prach_fmt >3) {
- dft(DFT_2048,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
+ prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=49152;
+ dft(DFT_49152,prach2,rxsigF[aa],1);
+ }
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
- dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
- dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_2048,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
- reps+=6;
+ if (prachFormat == 2) {
+ dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
+ dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
+ reps+=2;
+ }
+ if (prachFormat == 3) {
+ dftlen=12288;
+ for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
+ reps=4;
+ }
+ }// 839 sequence
+ else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=2048;
+ dft(DFT_2048,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) { // !=C0
+ dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
+ reps++;
+ }
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
+ dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
+ dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
+ reps+=6;
+ }
+ }
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
- } else {
+ } else { // threequarter sampling
// 40 MHz @ 46.08 Ms/s
- prach2 = prach[aa] + (3*Ncp);
- AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_36864,prach2,rxsigF[aa],1);
- reps++;
- }
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
- reps++;
- }
- if (prach_fmt == 2) {
- dft(DFT_36864,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
- dft(DFT_36864,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
- reps+=2;
- }
- if (prach_fmt == 3) {
- for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
- reps=4;
- }
- if (prach_fmt >3) {
- dft(DFT_1536,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
+ prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q
+ if (prach_sequence_length == 0) {
+ AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=36864;
+ dft(DFT_36864,prach2,rxsigF[aa],1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
- dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
- dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
- reps+=6;
- }
- }
- }
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
+ reps++;
+ }
+ if (prachFormat == 2) {
+ dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1);
+ dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1);
+ reps+=2;
+ }
+ if (prachFormat == 3) {
+ dftlen=9216;
+ for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
+ reps=4;
+ }
+ } else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only)
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=1536;
+ dft(DFT_1536,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) {
+ dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
+ reps++;
+ }
+
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
+ dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
+ dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
+ reps+=6;
+ }
+ }// mu==1
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
+ } // short format
+ } // 3/4 sampling
+ } // <=50 MHz BW
else if (fp->N_RB_UL <= 273) {
if (fp->threequarter_fs==0) {
prach2 = prach[aa] + (Ncp<<3);
- dftlen=98304;
- //80,90,100 MHz @ 61.44 Ms/s
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2)
- dft(DFT_98304,prach2,rxsigF[aa],1);
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
- reps++;
- }
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
- dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
- reps+=2;
- }
- if (prach_fmt == 3) {
- dft(DFT_24576,prach2+(2*49152),rxsigF[aa]+(2*49152),1);
- reps=4;
- dftlen=24576;
- }
- if (prach_fmt >3) {
- dftlen=4096;
- dft(DFT_4096,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
+ //80,90,100 MHz @ 122.88 Ms/s
+
+ if (prach_sequence_length == 0) {
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=98304;
+ dft(DFT_98304,prach2,rxsigF[aa],1);
+ }
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
- dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
- dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
- reps+=6;
+ if (prachFormat == 2) {
+ dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
+ dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1);
+ reps+=2;
+ }
+ if (prachFormat == 3) {
+ dftlen=24576;
+ for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1);
+ reps=4;
+ }
+ }
+ else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=4096;
+ dft(DFT_4096,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) { //!=C0
+ dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
+ reps++;
+ }
+
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
+ dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
+ dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
+ reps+=6;
+ }
+ }
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
} else {
AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n");
prach2 = prach[aa] + (6*Ncp);
- // 80 MHz @ 46.08 Ms/s
- dftlen=73728;
- if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_73728,prach2,rxsigF[aa],1);
- reps++;
- }
- if (prach_fmt == 1 || prach_fmt == 2) {
- dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
- reps++;
- }
- if (prach_fmt == 3) {
- dft(DFT_73728,prach2+(4*73728),rxsigF[aa]+(4*73728),1);
- reps=4;
- dftlen=18432;
- }
-
- if (prach_fmt >3) {
- dftlen=3072;
- dft(DFT_3072,prach2,rxsigF[aa],1);
- if (prach_fmt != 0xc0) {
- dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
+ // 80 MHz @ 92.16 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
+ dftlen=73728;
+ dft(DFT_73728,prach2,rxsigF[aa],1);
reps++;
}
- }
- if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) {
- dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
- dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
- reps+=2;
- }
- if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) {
- dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
- dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
- reps+=2;
- }
- if (prach_fmt == 0xc2) {
- for (int i=6;i<11;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
- reps+=6;
+ if (prachFormat == 1 || prachFormat == 2) {
+ dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
+ reps++;
+ }
+ if (prachFormat == 3) {
+ dftlen=18432;
+ for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1);
+ reps=4;
+ }
+ } else {
+ if ((mu==0 &&
+ (prachStartSymbol == 0 || prachStartSymbol == 7)) ||
+ (mu==1 && prachStartSymbol == 0)) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
+
+ if (mu==0) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==1) {
+ dftlen=3072;
+ dft(DFT_3072,prach2,rxsigF[aa],1);
+ if (prachFormat != 7) { //!=C0
+ dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
+ reps++;
+ }
+
+ if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
+ dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
+ dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
+ reps+=2;
+ }
+ if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
+ dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
+ dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
+ reps+=2;
+ }
+ if (prachFormat == 6) {
+ for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
+ reps+=6;
+ }
+ }
+ else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n");
+ else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n");
}
}
}
@@ -350,7 +508,7 @@ void rx_nr_prach_ru(RU_t *ru,
for (int j=0;jgNB_config.prach_config;
NR_DL_FRAME_PARMS *fp;
- lte_frame_type_t frame_type;
+
uint16_t rootSequenceIndex;
- uint8_t prach_ConfigIndex;
- uint8_t Ncs_config;
+ int numrootSequenceIndex;
uint8_t restricted_set;
uint8_t n_ra_prb;
int16_t *prachF=NULL;
@@ -404,59 +563,43 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32)));
int32_t *prach_ifft=(int32_t*)NULL;
- nr_frequency_range_e freq_range;
+ fp = &gNB->frame_parms;
- fp = &gNB->frame_parms;
- nb_rx = fp->nb_antennas_rx;
+ nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
- frame_type = fp->frame_type;
- freq_range = fp->freq_range;
- rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
- prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
- Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
- restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
-
+ rootSequenceIndex = cfg->num_prach_fd_occasions_list[0].prach_root_sequence_index.value;
+ numrootSequenceIndex = cfg->num_prach_fd_occasions_list[0].num_root_sequences.value;
+ NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
+ int prach_sequence_length = cfg->prach_sequence_length.value;
- uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,freq_range);
- uint16_t N_ZC = (prach_fmt <4)?839:139;
+ int msg1_frequencystart = cfg->num_prach_fd_occasions_list[0].k1.value;
+ // int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value;
+ // cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list
+
+ restricted_set = cfg->restricted_set_config.value;
+
+ AssertFatal(prach_sequence_length == 1, "no support yet for long prachSequenceLength\n");
+
+
+ uint8_t prach_fmt = prach_pdu->prach_format;
+ uint16_t N_ZC = (prach_sequence_length==0)?839:139;
+
+ LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d \n", rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC);
prach_ifft = gNB->prach_vars.prach_ifft;
prachF = gNB->prach_vars.prachF;
if (LOG_DEBUGFLAG(PRACH)){
- if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart,prach_ConfigIndex,rootSequenceIndex);
+ if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, rootSequenceIndex %d\n", subframe,msg1_frequencystart,rootSequenceIndex);
}
-
- int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
- if (prach_fmt<3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt==3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt>3){
- NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config];
- }
-
- AssertFatal(NCS!=99,"NCS has not been set\n");
-
start_meas(&gNB->rx_prach);
- prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
+
+ prach_root_sequence_map = (cfg->prach_sequence_length.value==0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
// PDP is oversampled, e.g. 1024 sample instead of 839
// Adapt the NCS (zero-correlation zones) with oversampling factor e.g. 1024/839
@@ -469,6 +612,9 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
*max_preamble_energy=0;
+ *max_preamble_delay=0;
+ *max_preamble=0;
+
for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
if (LOG_DEBUGFLAG(PRACH)){
@@ -478,7 +624,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
if (restricted_set == 0) {
// This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
-
+
if (preamble_offset != preamble_offset_old) {
preamble_offset_old = preamble_offset;
new_dft = 1;
@@ -508,13 +654,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
// current root depending on rootSequenceIndex
int index = (rootSequenceIndex + preamble_offset) % N_ZC;
- if (prach_fmt<4) {
- // prach_root_sequence_map points to prach_root_sequence_map0_3
- DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
- } else {
- // prach_root_sequence_map points to prach_root_sequence_map4
- DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) );
- }
u = prach_root_sequence_map[index];
uint16_t n_group_ra = 0;
@@ -559,14 +698,21 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
// Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
- if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, NCS_config %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
- frame,subframe,preamble_index,NCS,Ncs_config,N_ZC/NCS,preamble_offset,preamble_shift,en);
+ if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
+ frame,subframe,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en);
}
+ LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset);
+
+
if (new_dft == 1) {
new_dft = 0;
Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx];
+
+ LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx);
+
+
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
@@ -590,13 +736,13 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
idft(IDFT_1024,prachF,prach_ifft_tmp,1);
// compute energy and accumulate over receive antennas
for (i=0;i<2048;i++)
- prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[i<<1] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10;
+ prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
} else {
idft(IDFT_256,prachF,prach_ifft_tmp,1);
log2_ifft_size = 8;
// compute energy and accumulate over receive antennas and repetitions for BR
for (i=0;i<256;i++)
- prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[(i<<1)] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10;
+ prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10;
}
if (LOG_DUMPFLAG(PRACH)) {
@@ -614,7 +760,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
for (i=0; i*max_preamble_energy) {
*max_preamble_energy = levdB;
*max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate
@@ -623,6 +768,31 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
}
}// preamble_index
+
+ // The conversion from *max_preamble_delay from TA value is done here.
+ // It is normalized to the 30.72 Ms/s, considering the numerology, N_RB and the sampling rate
+ // See table 6.3.3.1 -1 and -2 in 38211.
+
+ // Format 0, 1, 2: 24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
+ // By solving:
+ // max_preamble_delay * ( (24576*(fs/30.72M)) / 1024 ) / fs = TA * 16 * 64 / 2^mu * Tc
+
+ // Format 3: 6144 samples @ 30.72 Ms/s, 24576 samples @ 122.88 Ms/s
+ // By solving:
+ // max_preamble_delay * ( (6144*(fs/30.72M)) / 1024 ) / fs = TA * 16 * 64 / 2^mu * Tc
+
+ // Format >3: 2048/2^mu samples @ 30.72 Ms/s, 2048/2^mu * 4 samples @ 122.88 Ms/s
+ // By solving:
+ // max_preamble_delay * ( (2048/2^mu*(fs/30.72M)) / 256 ) / fs = TA * 16 * 64 / 2^mu * Tc
+ uint16_t *TA = max_preamble_delay;
+ int mu = fp->numerology_index;
+ if (cfg->prach_sequence_length.value==0) {
+ if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) *TA = *TA*3*(1<60) {
@@ -641,7 +811,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
}
} /* LOG_DUMPFLAG(PRACH) */
- if (gNB) stop_meas(&gNB->rx_prach);
+ stop_meas(&gNB->rx_prach);
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.h b/openair1/PHY/NR_TRANSPORT/nr_prach.h
index 1e2b758035..d158e04c79 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.h
@@ -37,18 +37,6 @@ uint16_t nr_du[838];
/*************************************
* The following tables defined for NR
**************************************/
-// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
-uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419};
-uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case set Type A
-uint16_t NCS_restricted_TypeB_delta_f_RA_125[13] = {15,18,22,26,32,38,46,55,68,82,100,118,137}; // high-speed case set Type B
-
-// Table 6.3.3.1-6 (38.211) NCS for preamble formats with delta_f_RA = 5 KHz
-uint16_t NCS_unrestricted_delta_f_RA_5[16] = {0,13,26,33,38,41,49,55,64,76,93,119,139,209,279,419};
-uint16_t NCS_restricted_TypeA_delta_f_RA_5[16] = {36,57,72,81,89,94,103,112,121,132,137,152,173,195,216,237}; // high-speed case set Type A
-uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,85,97,109,122,137}; // high-speed case set Type B
-
-// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3}
-uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69};
//Table 6.3.3.1-3: Mapping from logical index i to sequence number u for preamble formats with L_RA = 839
uint16_t prach_root_sequence_map_0_3[838] = {
@@ -105,787 +93,3 @@ uint16_t prach_root_sequence_map_abc[138] = {
51, 88 , 52, 87 , 53, 86 , 54, 85 , 55, 84 , 56, 83 , 57, 82 , 58, 81 , 59, 80 , 60, 79 ,
61, 78 , 62, 77 , 63, 76 , 64, 75 , 65, 74 , 66, 73 , 67, 72 , 68, 71 , 69, 70
};
-
-// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
-// the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent.
-// E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9.
-// E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6
-int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = {
-//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
-{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
-{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
-{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
-{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
-{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
-{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
-{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
-{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
-{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
-{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
-{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
-{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
-{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
-{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
-{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
-{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
-{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
-{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9
-{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
-{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
-{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
-{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
-{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
-{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
-{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
-{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
-{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
-{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
-{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
-{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
-{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
-{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
-{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 8, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 4, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 4, 1, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 4, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 2, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 2, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
-{0xa1, -1, 2, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
-{0xa1, -1, 2, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
-{0xa1, -1, 1, 0, 16, 0, 1, 6, 2}, // (subframe number) 4
-{0xa1, -1, 1, 0, 66, 0, 1, 6, 2}, // (subframe number) 1,6
-{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
-{0xa1, -1, 1, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
-{0xa1, -1, 1, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
-{0xa1, -1, 1, 0, 132, 0, 2, 6, 2}, // (subframe number) 2,7
-{0xa1, -1, 1, 0, 146, 0, 2, 6, 2}, // (subframe number) 1,4,7
-{0xa1, -1, 1, 0, 341, 0, 2, 6, 2}, // (subframe number) 0,2,4,6,8
-{0xa1, -1, 1, 0, 1023, 0, 2, 6, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa1, -1, 1, 0, 682, 0, 2, 6, 2}, // (subframe number) 1,3,5,7,9
-{0xa1, 0xb1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xa1, 0xb1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xa1, 0xb1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
-{0xa1, 0xb1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
-{0xa1, 0xb1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xa1, 0xb1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xa1, 0xb1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xa1, 0xb1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
-{0xa1, 0xb1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
-{0xa2, -1, 16, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 16, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 8, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 8, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 4, 0, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 4, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, -1, 2, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
-{0xa2, -1, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, -1, 2, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
-{0xa2, -1, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
-{0xa2, -1, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
-{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
-{0xa2, -1, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
-{0xa2, -1, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
-{0xa2, -1, 1, 0, 132, 0, 2, 3, 4}, // (subframe number) 2,7
-{0xa2, -1, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
-{0xa2, -1, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
-{0xa2, -1, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa2, -1, 1, 0, 682, 0, 2, 3, 4}, // (subframe number) 1,3,5,7,9
-{0xa2, 0xb2, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
-{0xa2, 0xb2, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
-{0xa2, 0xb2, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
-{0xa2, 0xb2, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
-{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
-{0xa2, 0xb2, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
-{0xa2, 0xb2, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
-{0xa2, 0xb2, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
-{0xa2, 0xb2, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
-{0xa2, 0xb2, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa3, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
-{0xa3, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xa3, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xa3, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
-{0xa3, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
-{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xa3, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xa3, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
-{0xa3, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
-{0xa3, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
-{0xa3, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xa3, -1, 1, 0, 682, 0, 2, 2, 6}, // (subframe number) 1,3,5,7,9
-{0xa3, 0xb3, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
-{0xa3, 0xb3, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xa3, 0xb3, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
-{0xa3, 0xb3, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
-{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xa3, 0xb3, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xa3, 0xb3, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xa3, 0xb3, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
-{0xa3, 0xb3, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
-{0xa3, 0xb3, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xb1, -1, 16, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 16, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 8, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 4, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xb1, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xb1, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xb1, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
-{0xb1, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
-{0xb1, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xb1, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xb1, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xb1, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
-{0xb1, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
-{0xb1, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
-{0xb1, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xb1, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
-{0xb4, -1, 16, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 16, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 8, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 8, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 4, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 4, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 4, 1, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 2, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 2, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
-{0xb4, -1, 2, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 2, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
-{0xb4, -1, 1, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
-{0xb4, -1, 1, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
-{0xb4, -1, 1, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
-{0xb4, -1, 1, 0, 66, 0, 2, 1, 12}, // (subframe number) 1,6
-{0xb4, -1, 1, 0, 132, 0, 2, 1, 12}, // (subframe number) 2,7
-{0xb4, -1, 1, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
-{0xb4, -1, 1, 0, 146, 0, 2, 1, 12}, // (subframe number) 1,4,7
-{0xb4, -1, 1, 0, 341, 0, 2, 1, 12}, // (subframe number) 0,2,4,6,8
-{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xb4, -1, 1, 0, 682, 0, 2, 1, 12}, // (subframe number) 1,3,5,7,9
-{0xc0, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xc0, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xc0, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xc0, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xc0, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xc0, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
-{0xc0, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xc0, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
-{0xc0, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
-{0xc0, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
-{0xc0, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
-{0xc0, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
-{0xc0, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
-{0xc0, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
-{0xc0, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
-{0xc0, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xc0, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
-{0xc2, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
-{0xc2, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xc2, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
-{0xc2, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xc2, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
-{0xc2, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
-{0xc2, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
-{0xc2, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
-{0xc2, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
-{0xc2, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
-{0xc2, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
-{0xc2, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
-{0xc2, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
-{0xc2, -1, 1, 0, 682, 0, 2, 2, 6} // (subframe number) 1,3,5,7,9
-};
-// Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum
-int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = {
-//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
-{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
-{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
-{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
-{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
-{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
-{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
-{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
-{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
-{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
-{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
-{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
-{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
-{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
-{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
-{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
-{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
-{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9)
-{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
-{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
-{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
-{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
-{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
-{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
-{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
-{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6)
-{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
-{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
-{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
-{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
-{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
-{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
-{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
-{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
-{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
-{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
-{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
-{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
-{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
-{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
-{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
-{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
-{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
-{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
-{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
-{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
-{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
-{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
-{0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
-{0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
-{0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
-{0xa1, -1, 2, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
-{0xa1, -1, 2, 1, 528, 7, 1, 3, 2}, // (subrame number 4,9)
-{0xa1, -1, 2, 1, 640, 7, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, -1, 2, 1, 640, 0, 1, 6, 2}, // (subrame number 7,9)
-{0xa1, -1, 2, 1, 768, 0, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, -1, 2, 1, 528, 0, 2, 6, 2}, // (subrame number 4,9)
-{0xa1, -1, 2, 1, 924, 0, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
-{0xa1, -1, 1, 0, 512, 0, 2, 6, 2}, // (subrame number 9)
-{0xa1, -1, 1, 0, 512, 7, 1, 3, 2}, // (subrame number 9)
-{0xa1, -1, 1, 0, 512, 0, 1, 6, 2}, // (subrame number 9)
-{0xa1, -1, 1, 0, 768, 0, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subrame number 4,9)
-{0xa1, -1, 1, 0, 640, 7, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, -1, 1, 0, 792, 0, 1, 6, 2}, // (subrame number 3,4,8,9)
-{0xa1, -1, 1, 0, 792, 0, 2, 6, 2}, // (subrame number 3,4,8,9)
-{0xa1, -1, 1, 0, 682, 0, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xa1, -1, 1, 0, 1023, 7, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa2, -1, 16, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, -1, 8, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, -1, 4, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, -1, 2, 1, 640, 0, 1, 3, 4}, // (subrame number 7,9)
-{0xa2, -1, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, -1, 2, 1, 640, 9, 1, 1, 4}, // (subrame number 7,9)
-{0xa2, -1, 2, 1, 528, 9, 1, 1, 4}, // (subrame number 4,9)
-{0xa2, -1, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
-{0xa2, -1, 16, 1, 924, 0, 1, 3, 4}, // (subrame number 2,3,4,7,8,9)
-{0xa2, -1, 1, 0, 4, 0, 1, 3, 4}, // (subrame number 2)
-{0xa2, -1, 1, 0, 128, 0, 1, 3, 4}, // (subrame number 7)
-{0xa2, -1, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 512, 9, 1, 1, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, -1, 1, 0, 132, 0, 1, 3, 4}, // (subrame number 2,7)
-{0xa2, -1, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
-{0xa2, -1, 1, 0, 640, 9, 1, 1, 4}, // (subrame number 7,9)
-{0xa2, -1, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, -1, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, -1, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
-{0xa2, -1, 1, 0, 1023, 9, 1, 1, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa3, -1, 16, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, -1, 8, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, -1, 4, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, -1, 2, 1, 528, 7, 1, 1, 6}, // (subrame number 4,9)
-{0xa3, -1, 2, 1, 640, 7, 1, 1, 6}, // (subrame number 7,9)
-{0xa3, -1, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, -1, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
-{0xa3, -1, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, -1, 2, 1, 924, 0, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
-{0xa3, -1, 1, 0, 4, 0, 1, 2, 6}, // (subrame number 2)
-{0xa3, -1, 1, 0, 128, 0, 1, 2, 6}, // (subrame number 7)
-{0xa3, -1, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 512, 7, 1, 1, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, -1, 1, 0, 132, 0, 1, 2, 6}, // (subrame number 2,7)
-{0xa3, -1, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
-{0xa3, -1, 1, 0, 640, 7, 1, 1, 6}, // (subrame number 7,9)
-{0xa3, -1, 1, 0, 792, 0, 1, 2, 6}, // (subrame number 3,4,8,9)
-{0xa3, -1, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
-{0xa3, -1, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
-{0xa3, -1, 1, 0, 1023, 7, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xb1, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xb1, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xb1, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
-{0xb1, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
-{0xb1, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
-{0xb1, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xb1, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
-{0xb1, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xb1, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xb1, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
-{0xb1, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xb1, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xb4, -1, 16, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
-{0xb4, -1, 8, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
-{0xb4, -1, 4, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 2, 1, 512, 0, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 2, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 2, 1, 640, 2, 1, 1, 12}, // (subrame number 7,9)
-{0xb4, -1, 2, 1, 528, 2, 1, 1, 12}, // (subrame number 4,9)
-{0xb4, -1, 2, 1, 528, 0, 2, 1, 12}, // (subrame number 4,9)
-{0xb4, -1, 2, 1, 768, 0, 2, 1, 12}, // (subrame number 8,9)
-{0xb4, -1, 2, 1, 924, 0, 1, 1, 12}, // (subrame number 2,3,4,7,8,9)
-{0xb4, -1, 1, 0, 2, 0, 1, 1, 12}, // (subrame number 1)
-{0xb4, -1, 1, 0, 4, 0, 1, 1, 12}, // (subrame number 2)
-{0xb4, -1, 1, 0, 16, 0, 1, 1, 12}, // (subrame number 4)
-{0xb4, -1, 1, 0, 128, 0, 1, 1, 12}, // (subrame number 7)
-{0xb4, -1, 1, 0, 512, 0, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 1, 0, 512, 2, 1, 1, 12}, // (subrame number 9)
-{0xb4, -1, 1, 0, 512, 0, 2, 1, 12}, // (subrame number 9)
-{0xb4, -1, 1, 0, 528, 2, 1, 1, 12}, // (subrame number 4,9)
-{0xb4, -1, 1, 0, 640, 2, 1, 1, 12}, // (subrame number 7,9)
-{0xb4, -1, 1, 0, 768, 0, 2, 1, 12}, // (subrame number 8,9)
-{0xb4, -1, 1, 0, 792, 2, 1, 1, 12}, // (subrame number 3,4,8,9)
-{0xb4, -1, 1, 0, 682, 2, 1, 1, 12}, // (subrame number 1,3,5,7,9)
-{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xb4, -1, 1, 0, 1023, 2, 1, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xc0, -1, 16, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xc0, -1, 8, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xc0, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xc0, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xc0, -1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xc0, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
-{0xc0, -1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xc0, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
-{0xc0, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
-{0xc0, -1, 2, 1, 924, 2, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
-{0xc0, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xc0, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
-{0xc0, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xc0, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xc0, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
-{0xc0, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xc0, -1, 1, 0, 792, 2, 1, 6, 2}, // (subrame number 3,4,8,9)
-{0xc0, -1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
-{0xc0, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xc0, -1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xc2, -1, 16, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
-{0xc2, -1, 8, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
-{0xc2, -1, 4, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xc2, -1, 2, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xc2, -1, 2, 1, 768, 2, 2, 2, 6}, // (subrame number 8,9)
-{0xc2, -1, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
-{0xc2, -1, 2, 1, 640, 8, 1, 1, 6}, // (subrame number 7,9)
-{0xc2, -1, 2, 1, 528, 8, 1, 1, 6}, // (subrame number 4,9)
-{0xc2, -1, 2, 1, 528, 2, 2, 2, 6}, // (subrame number 4,9)
-{0xc2, -1, 2, 1, 924, 2, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
-{0xc2, -1, 8, 1, 512, 8, 2, 1, 6}, // (subrame number 9)
-{0xc2, -1, 4, 1, 512, 8, 1, 1, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 512, 2, 2, 2, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 512, 8, 1, 1, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xc2, -1, 1, 0, 768, 2, 2, 2, 6}, // (subrame number 8,9)
-{0xc2, -1, 1, 0, 528, 2, 1, 2, 6}, // (subrame number 4,9)
-{0xc2, -1, 1, 0, 640, 8, 1, 1, 6}, // (subrame number 7,9)
-{0xc2, -1, 1, 0, 792, 2, 1, 2, 6}, // (subrame number 3,4,8,9)
-{0xc2, -1, 1, 0, 792, 2, 2, 2, 6}, // (subrame number 3,4,8,9)
-{0xc2, -1, 1, 0, 682, 2, 1, 2, 6}, // (subrame number 1,3,5,7,9)
-{0xc2, -1, 1, 0, 1023, 8, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa1, 0xb1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xa1, 0xb1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
-{0xa1, 0xb1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, 0xb1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
-{0xa1, 0xb1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
-{0xa1, 0xb1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, 0xb1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
-{0xa1, 0xb1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
-{0xa1, 0xb1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
-{0xa1, 0xb1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
-{0xa1, 0xb1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
-{0xa1, 0xb1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
-{0xa1, 0xb1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
-{0xa1, 0xb1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
-{0xa1, 0xb1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa2, 0xb2, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, 0xb2, 2, 1, 528, 6, 1, 2, 4}, // (subrame number 4,9)
-{0xa2, 0xb2, 2, 1, 640, 6, 1, 2, 4}, // (subrame number 7,9)
-{0xa2, 0xb2, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
-{0xa2, 0xb2, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, 0xb2, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
-{0xa2, 0xb2, 1, 0, 512, 6, 1, 2, 4}, // (subrame number 9)
-{0xa2, 0xb2, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
-{0xa2, 0xb2, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
-{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
-{0xa2, 0xb2, 1, 0, 640, 6, 1, 2, 4}, // (subrame number 7,9)
-{0xa2, 0xb2, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, 0xb2, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
-{0xa2, 0xb2, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
-{0xa2, 0xb2, 1, 0, 1023, 6, 1, 2, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
-{0xa3, 0xb3, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 2, 1, 528, 2, 1, 2, 6}, // (subrame number 4,9)
-{0xa3, 0xb3, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, 0xb3, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, 0xb3, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
-{0xa3, 0xb3, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, 0xb3, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
-{0xa3, 0xb3, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
-{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
-{0xa3, 0xb3, 1, 0, 640, 2, 1, 2, 6}, // (subrame number 7,9)
-{0xa3, 0xb3, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
-{0xa3, 0xb3, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
-{0xa3, 0xb3, 1, 0, 1023, 2, 1, 2, 6} // (subrame number 0,1,2,3,4,5,6,7,8,9)
-};
-// Table 6.3.3.2-4: Random access configurations for FR2 and unpaired spectrum
-int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = {
-//format, format, x, y, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
-{0xa1, -1, 16, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 16, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 8, 1, 2, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xa1, -1, 8, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 8, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 4, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 4, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 4, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 2, 1, -1, 551911719040, 0, 2, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xa1, -1, 2, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 2, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 2, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 549756338176, 7, 1, 3, 2}, // (subframe number :19,39)
-{0xa1, -1, 1, 0, -1, 168, 0, 1, 6, 2}, // (subframe number :3,5,7)
-{0xa1, -1, 1, 0, -1, 567489331200, 7, 1, 3, 2}, // (subframe number :24,29,34,39)
-{0xa1, -1, 1, 0, -1, 550293209600, 7, 2, 3, 2}, // (subframe number :9,19,29,39)
-{0xa1, -1, 1, 0, -1, 687195422720, 0, 1, 6, 2}, // (subframe number :17,19,37,39)
-{0xa1, -1, 1, 0, -1, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xa1, -1, 1, 0, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 1, 0, -1, 567489872400, 7, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, -1, 1, 0, -1, 10920, 7, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
-{0xa1, -1, 1, 0, -1, 586405642240, 7, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 551911719040, 0, 1, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xa1, -1, 1, 0, -1, 586405642240, 0, 1, 6, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 965830828032, 7, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xa1, -1, 1, 0, -1, 586406201480, 7, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, -1, 1, 0, -1, 733007751850, 0, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xa1, -1, 1, 0, -1, 1099511627775, 7, 1, 3, 2}, // (subframe number :0,1,2,…,39)
-{0xa2, -1, 16, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 16, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 8, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 8, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 8, 1, 2, 550293209600, 0, 2, 3, 4}, // (subframe number :9,19,29,39)
-{0xa2, -1, 4, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 4, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 4, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 2, 1, -1, 551911719040, 0, 2, 3, 4}, // (subframe number :7,15,23,31,39)
-{0xa2, -1, 2, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 2, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 2, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 549756338176, 5, 1, 2, 4}, // (subframe number :19,39)
-{0xa2, -1, 1, 0, -1, 168, 0, 1, 3, 4}, // (subframe number :3,5,7)
-{0xa2, -1, 1, 0, -1, 567489331200, 5, 1, 2, 4}, // (subframe number :24,29,34,39)
-{0xa2, -1, 1, 0, -1, 550293209600, 5, 2, 2, 4}, // (subframe number :9,19,29,39)
-{0xa2, -1, 1, 0, -1, 687195422720, 0, 1, 3, 4}, // (subframe number :17,19,37,39)
-{0xa2, -1, 1, 0, -1, 550293209600, 0, 2, 3, 4}, // (subframe number :9, 19, 29, 39)
-{0xa2, -1, 1, 0, -1, 551911719040, 0, 1, 3, 4}, // (subframe number :7,15,23,31,39)
-{0xa2, -1, 1, 0, -1, 586405642240, 5, 1, 2, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 586405642240, 0, 1, 3, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 10920, 5, 1, 2, 4}, // (subframe number :3,5,7,9,11,13)
-{0xa2, -1, 1, 0, -1, 10920, 0, 1, 3, 4}, // (subframe number :3,5,7,9,11,13)
-{0xa2, -1, 1, 0, -1, 567489872400, 5, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 1, 0, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, -1, 1, 0, -1, 965830828032, 5, 2, 2, 4}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xa2, -1, 1, 0, -1, 586406201480, 5, 1, 2, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, -1, 1, 0, -1, 733007751850, 0, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
-{0xa2, -1, 1, 0, -1, 1099511627775, 5, 1, 2, 4}, // (subframe number :0,1,2,…,39)
-{0xa3, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 549756338176, 7, 1, 1, 6}, // (subframe number :19,39)
-{0xa3, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
-{0xa3, -1, 1, 0, -1, 10752, 2, 1, 2, 6}, // (subframe number :9,11,13)
-{0xa3, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
-{0xa3, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
-{0xa3, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
-{0xa3, -1, 1, 0, -1, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, -1, 1, 0, -1, 551911719040, 0, 1, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xa3, -1, 1, 0, -1, 586405642240, 7, 1, 1, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 10920, 0, 1, 2, 6}, // (subframe number :3,5,7,9,11,13)
-{0xa3, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
-{0xa3, -1, 1, 0, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 1, 0, -1, 567489872400, 7, 1, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xa3, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
-{0xa3, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
-{0xb1, -1, 16, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 8, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 8, 1, 2, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xb1, -1, 4, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 2, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 2, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
-{0xb1, -1, 1, 0, -1, 168, 2, 1, 6, 2}, // (subframe number :3,5,7)
-{0xb1, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
-{0xb1, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
-{0xb1, -1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
-{0xb1, -1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xb1, -1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xb1, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
-{0xb1, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb1, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xb1, -1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb1, -1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xb1, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
-{0xb4, -1, 16, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 16, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 8, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 8, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 8, 1, 2, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
-{0xb4, -1, 4, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 4, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 4, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 2, 1, -1, 551911719040, 2, 2, 1, 12}, // (subframe number :7,15,23,31,39)
-{0xb4, -1, 2, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 2, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 2, 1, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 549756338176, 2, 2, 1, 12}, // (subframe number :19, 39)
-{0xb4, -1, 1, 0, -1, 687195422720, 0, 1, 1, 12}, // (subframe number :17, 19, 37, 39)
-{0xb4, -1, 1, 0, -1, 567489331200, 2, 1, 1, 12}, // (subframe number :24,29,34,39)
-{0xb4, -1, 1, 0, -1, 550293209600, 2, 2, 1, 12}, // (subframe number :9,19,29,39)
-{0xb4, -1, 1, 0, -1, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
-{0xb4, -1, 1, 0, -1, 551911719040, 0, 1, 1, 12}, // (subframe number :7,15,23,31,39)
-{0xb4, -1, 1, 0, -1, 551911719040, 0, 2, 1, 12}, // (subframe number :7,15,23,31,39)
-{0xb4, -1, 1, 0, -1, 586405642240, 0, 1, 1, 12}, // (subframe number :23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 586405642240, 2, 2, 1, 12}, // (subframe number :23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 698880, 0, 1, 1, 12}, // (subframe number :9,11,13,15,17,19)
-{0xb4, -1, 1, 0, -1, 10920, 2, 1, 1, 12}, // (subframe number :3,5,7,9,11,13)
-{0xb4, -1, 1, 0, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 1, 0, -1, 567489872400, 2, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xb4, -1, 1, 0, -1, 965830828032, 2, 2, 1, 12}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xb4, -1, 1, 0, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 586406201480, 2, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xb4, -1, 1, 0, -1, 44739240, 2, 1, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
-{0xb4, -1, 1, 0, -1, 44739240, 0, 2, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
-{0xb4, -1, 1, 0, -1, 733007751850, 0, 1, 1, 12}, // (subframe number :1,3,5,7,…,37,39)
-{0xb4, -1, 1, 0, -1, 1099511627775, 2, 1, 1, 12}, // (subframe number :0, 1, 2,…, 39)
-{0xc0, -1, 16, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 16, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 8, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 8, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 8, 1, 2, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
-{0xc0, -1, 4, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 4, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 4, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 2, 1, -1, 551911719040, 0, 2, 7, 2}, // (subframe number :7,15,23,31,39)
-{0xc0, -1, 2, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 2, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 2, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
-{0xc0, -1, 1, 0, -1, 168, 0, 1, 7, 2}, // (subframe number :3,5,7)
-{0xc0, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
-{0xc0, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
-{0xc0, -1, 1, 0, -1, 687195422720, 0, 1, 7, 2}, // (subframe number :17,19,37,39)
-{0xc0, -1, 1, 0, -1, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
-{0xc0, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 551911719040, 0, 1, 7, 2}, // (subframe number :7,15,23,31,39)
-{0xc0, -1, 1, 0, -1, 586405642240, 0, 1, 7, 2}, // (subframe number :23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
-{0xc0, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 1, 0, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc0, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xc0, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc0, -1, 1, 0, -1, 733007751850, 0, 1, 7, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xc0, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
-{0xc2, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xc2, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 2, 1, -1, 551911719040, 2, 2, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xc2, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
-{0xc2, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
-{0xc2, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
-{0xc2, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
-{0xc2, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
-{0xc2, -1, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xc2, -1, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xc2, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
-{0xc2, -1, 1, 0, -1, 586405642240, 7, 2, 1, 6}, // (subframe number :23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 567489872400, 7, 2, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xc2, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
-{0xc2, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xc2, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
-{0xc2, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
-{0xa1, 0xb1, 16, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 16, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 8, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 8, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 4, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 4, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 2, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
-{0xa1, 0xb1, 1, 0, -1, 550293209600, 8, 1, 3, 2}, // (subframe number :9,19,29,39)
-{0xa1, 0xb1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
-{0xa1, 0xb1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
-{0xa1, 0xb1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, 0xb1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
-{0xa1, 0xb1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
-{0xa1, 0xb1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa1, 0xb1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa1, 0xb1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
-{0xa2, 0xb2, 16, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 16, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 8, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 8, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 4, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 4, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 2, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 1, 0, -1, 549756338176, 6, 1, 2, 4}, // (subframe number :19,39)
-{0xa2, 0xb2, 1, 0, -1, 550293209600, 6, 1, 2, 4}, // (subframe number :9,19,29,39)
-{0xa2, 0xb2, 1, 0, -1, 687195422720, 2, 1, 3, 4}, // (subframe number :17,19,37,39)
-{0xa2, 0xb2, 1, 0, -1, 550293209600, 2, 2, 3, 4}, // (subframe number :9,19,29,39)
-{0xa2, 0xb2, 1, 0, -1, 586405642240, 6, 1, 2, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, 0xb2, 1, 0, -1, 551911719040, 2, 1, 3, 4}, // (subframe number :7,15,23,31,39)
-{0xa2, 0xb2, 1, 0, -1, 586405642240, 2, 1, 3, 4}, // (subframe number :23,27,31,35,39)
-{0xa2, 0xb2, 1, 0, -1, 567489872400, 6, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 1, 0, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa2, 0xb2, 1, 0, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa2, 0xb2, 1, 0, -1, 733007751850, 2, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
-{0xa3, 0xb3, 16, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 16, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 8, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 8, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 4, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 4, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 2, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
-{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 1, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, 0xb3, 1, 0, -1, 687195422720, 2, 1, 2, 6}, // (subframe number :17,19,37,39)
-{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
-{0xa3, 0xb3, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
-{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 1, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 2, 2, 6}, // (subframe number :23,27,31,35,39)
-{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
-{0xa3, 0xb3, 1, 0, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
-{0xa3, 0xb3, 1, 0, -1, 733007751850, 2, 1, 2, 6} // (subframe number :1,3,5,7,…,37,39)
-};
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
index e1b80a87a2..251d1cbfd8 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
@@ -34,15 +34,15 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/NR_TRANSPORT/nr_prach.h"
-#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
-
+#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "T.h"
-void init_nr_prach_tables(int N_ZC);
-void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) {
+
+/*void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) {
FILE *fd;
@@ -76,23 +76,13 @@ void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) {
fprintf(fd,"prach_config: n_ra_prboffset = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.msg1_frequencystart);
fclose(fd);
-}
+}*/
// This function computes the du
-void nr_fill_du(uint8_t prach_fmt)
+void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map)
{
uint16_t iu,u,p;
- uint16_t N_ZC;
- uint16_t *prach_root_sequence_map;
-
- if (prach_fmt<4) {
- N_ZC = 839;
- prach_root_sequence_map = prach_root_sequence_map_0_3;
- } else {
- N_ZC = 139;
- prach_root_sequence_map = prach_root_sequence_map_abc;
- }
for (iu=0; iu<(N_ZC-1); iu++) {
@@ -107,210 +97,45 @@ void nr_fill_du(uint8_t prach_fmt)
}
-int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) {
-
- uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
- /*
- // For FR1 paired
- if (((frame%table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][3]) &&
- ((table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][4]&(1<slots_per_subframe;
- // when were in the last slot of the subframe and this is a PRACH subframe ,return 1
- if (((slot%fp->slots_per_subframe) == fp->slots_per_subframe-1)&&
- (is_nr_prach_subframe(fp,frame,subframe))) return (1);
- else return(0);
-}
-
-uint16_t get_nr_prach_fmt(int prach_ConfigIndex,lte_frame_type_t frame_type, nr_frequency_range_e fr)
-{
-
- if (frame_type==FDD) return (table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
- else if (fr==nr_FR1) return (table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum
- else AssertFatal(1==0,"FR2 prach configuration not supported yet\n");
- // For FR2 not implemented. FIXME
-}
-
-void compute_nr_prach_seq(uint16_t rootSequenceIndex,
- uint8_t prach_ConfigIndex,
- uint8_t zeroCorrelationZoneConfig,
- uint8_t highSpeedFlag,
- lte_frame_type_t frame_type,
- nr_frequency_range_e fr,
- uint32_t X_u[64][839])
-{
+void compute_nr_prach_seq(uint8_t short_sequence,
+ uint8_t num_sequences,
+ uint8_t rootSequenceIndex,
+ uint32_t X_u[64][839]){
// Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC)
- unsigned int k,inv_u,i,NCS=0,num_preambles;
+ unsigned int k,inv_u,i;
int N_ZC;
- uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,fr);
+
uint16_t *prach_root_sequence_map;
- uint16_t u, preamble_offset;
- uint16_t n_shift_ra,n_shift_ra_bar, d_start,numshift;
- uint8_t not_found;
+ uint16_t u;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_IN);
-#ifdef NR_PRACH_DEBUG
- LOG_I(PHY,"compute_prach_seq: NCS_config %d, prach_fmt %x\n",zeroCorrelationZoneConfig, prach_fmt);
-#endif
+ LOG_D(PHY,"compute_prach_seq: prach short sequence %x, num_sequences %d, rootSequenceIndex %d\n", short_sequence, num_sequences, rootSequenceIndex);
-
- N_ZC = (prach_fmt < 4) ? 839 : 139;
+ N_ZC = (short_sequence) ? 139 : 839;
//init_prach_tables(N_ZC); //moved to phy_init_lte_ue/eNB, since it takes to long in real-time
init_nr_prach_tables(N_ZC);
- if (prach_fmt < 4) {
- prach_root_sequence_map = prach_root_sequence_map_0_3;
- } else {
+ if (short_sequence) {
// FIXME cannot be reached
prach_root_sequence_map = prach_root_sequence_map_abc;
- }
-
-
-#ifdef PRACH_DEBUG
- LOG_I( PHY, "compute_prach_seq: done init prach_tables\n" );
-#endif
-
-
-
-
- int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
-
- if (highSpeedFlag== 0) {
-
-#ifdef PRACH_DEBUG
- LOG_I(PHY,"Low speed prach : NCS_config %d\n",zeroCorrelationZoneConfig);
-#endif
-
- AssertFatal(zeroCorrelationZoneConfig<=15,
- "FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", zeroCorrelationZoneConfig );
- if (prach_fmt<3) NCS = NCS_unrestricted_delta_f_RA_125[zeroCorrelationZoneConfig];
- if (prach_fmt==3) NCS = NCS_unrestricted_delta_f_RA_5[zeroCorrelationZoneConfig];
- if (prach_fmt>3) NCS = NCS_unrestricted_delta_f_RA_15[zeroCorrelationZoneConfig];
-
- num_preambles = (NCS==0) ? 64 : ((64*NCS)/N_ZC);
-
- if (NCS>0) num_preambles++;
-
- preamble_offset = 0;
} else {
-
-#ifdef PRACH_DEBUG
- LOG_I( PHY, "high speed prach : NCS_config %"PRIu8"\n", zeroCorrelationZoneConfig );
-#endif
-
- AssertFatal(zeroCorrelationZoneConfig<=14,
- "FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", zeroCorrelationZoneConfig );
- if (prach_fmt<3){
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME
- }
- if (prach_fmt==3){
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME
- }
- if (prach_fmt>3){
-
- }
-
- nr_fill_du(prach_fmt);
-
- num_preambles = 64; // compute ZC sequence for 64 possible roots
- // find first non-zero shift root (stored in preamble_offset)
- not_found = 1;
- preamble_offset = 0;
-
- while (not_found == 1) {
- // current root depending on rootSequenceIndex
- int index = (rootSequenceIndex + preamble_offset) % N_ZC;
-
- if (prach_fmt<4) {
- // prach_root_sequence_map points to prach_root_sequence_map0_3
- DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
- } else {
- // prach_root_sequence_map points to prach_root_sequence_map4
- DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) );
- }
-
- u = prach_root_sequence_map[index];
-
- uint16_t n_group_ra = 0;
-
- if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
- n_shift_ra = nr_du[u]/NCS;
- d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
- n_group_ra = N_ZC/d_start;
- n_shift_ra_bar = max(0,(N_ZC-(nr_du[u]<<1)-(n_group_ra*d_start))/N_ZC);
- } else if ( (nr_du[u]>=(N_ZC/3)) && (nr_du[u]<=((N_ZC - NCS)>>1)) ) {
- n_shift_ra = (N_ZC - (nr_du[u]<<1))/NCS;
- d_start = N_ZC - (nr_du[u]<<1) + (n_shift_ra * NCS);
- n_group_ra = nr_du[u]/d_start;
- n_shift_ra_bar = min(n_shift_ra,max(0,(nr_du[u]- (n_group_ra*d_start))/NCS));
- } else {
- n_shift_ra = 0;
- n_shift_ra_bar = 0;
- }
-
- // This is the number of cyclic shifts for the current root u
- numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar;
-
- // skip to next root and recompute parameters if numshift==0
- if (numshift>0)
- not_found = 0;
- else
- preamble_offset++;
- }
+ prach_root_sequence_map = prach_root_sequence_map_0_3;
}
-#ifdef PRACH_DEBUG
+ LOG_D( PHY, "compute_prach_seq: done init prach_tables\n" );
- if (NCS>0)
- LOG_I( PHY, "Initializing %u preambles for PRACH (NCS_config %"PRIu8", NCS %u, N_ZC/NCS %u)\n",
- num_preambles, zeroCorrelationZoneConfig, NCS, N_ZC/NCS );
+ for (i=0; i
-#include "nfapi_interface.h"
-
-// Functions below implement 36-211 and 36-212
-
-/** @addtogroup _PHY_TRANSPORT_
- * @{
- */
-
-void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
-
-int rx_pmch(PHY_VARS_NR_UE *phy_vars_ue,
- unsigned char eNB_id,
- uint8_t subframe,
- unsigned char symbol);
-
-/** \brief Dump OCTAVE/MATLAB files for PMCH debugging
- @param phy_vars_ue Pointer to UE variables
- @param eNB_id index of eNB in ue variables
- @param coded_bits_per_codeword G from 36.211
- @param subframe Index of subframe
- @returns 0 on success
-*/
-void dump_mch(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe);
-
-
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qpsk_qpsk(int16_t *stream0_in,
- int16_t *stream1_in,
- int16_t *stream0_out,
- int16_t *rho01,
- int32_t length);
-
-/** \brief This function perform LLR computation for dual-stream (QPSK/QPSK) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr*/
-int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint16_t pbch_pss_sss_adj,
- int16_t **llr128p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qpsk_qam16(int16_t *stream0_in,
- int16_t *stream1_in,
- short *ch_mag_i,
- int16_t *stream0_out,
- int16_t *rho01,
- int32_t length);
-
-/** \brief This function perform LLR computation for dual-stream (QPSK/16QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr*/
-int32_t nr_dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint16_t pbch_pss_sss_adj,
- int16_t **llr128p);
-
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qpsk_qam64(int16_t *stream0_in,
- int16_t *stream1_in,
- short *ch_mag_i,
- int16_t *stream0_out,
- int16_t *rho01,
- int32_t length);
-
-/** \brief This function perform LLR computation for dual-stream (QPSK/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr*/
-int32_t nr_dlsch_qpsk_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint16_t pbch_pss_sss_adj,
- int16_t **llr128p);
-
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/QPSK reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam16_qpsk(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *stream0_out,
- short *rho01,
- int length);
-/** \brief This function perform LLR computation for dual-stream (16QAM/QPSK) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam16_qam16(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (16QAM/16QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- uint32_t len,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 16QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam16_qam64(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (16QAM/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_16qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
- int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qpsk(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (64QAM/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag,
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam16(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/16QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam16_avx2(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (64QAM/16QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_64qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag,
- int **dl_ch_mag_i,
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- short **llr16p);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam64(short *stream0_in,
- short *stream1_in,
- short *ch_mag,
- short *ch_mag_i,
- short *stream0_out,
- short *rho01,
- int length);
-
-/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception.
- @param stream0_in Input from channel compensated (MR combined) stream 0
- @param stream1_in Input from channel compensated (MR combined) stream 1
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param stream0_out Output from LLR unit for stream0
- @param rho01 Cross-correlation between channels (MR combined)
- @param length in complex channel outputs*/
-void qam64_qam64_avx2(int32_t *stream0_in,
- int32_t *stream1_in,
- int32_t *ch_mag,
- int32_t *ch_mag_i,
- int16_t *stream0_out,
- int32_t *rho01,
- int length);
-
-/** \brief This function perform LLR computation for dual-stream (64QAM/64QAM) transmission.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param ch_mag Input from scaled channel magnitude square of h0'*g0
- @param ch_mag_i Input from scaled channel magnitude square of h0'*g1
- @param rho_i Correlation between channel of signal and inteference
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag flag to indicate this is the first symbol of the dlsch
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr16p pointer to pointer to symbol in dlsch_llr*/
-int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **dl_ch_mag,
- int **dl_ch_mag_i,
- int **rho_i,
- short *dlsch_llr,
- unsigned char symbol,
- uint32_t len,
- unsigned char first_symbol_flag,
- unsigned short nb_rb,
- uint16_t pbch_pss_sss_adjust,
- //short **llr16p,
- uint32_t llr_offset);
-
-
-/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dlsch_llr llr output
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
- @param llr128p pointer to pointer to symbol in dlsch_llr
- @param beamforming_mode beamforming mode
-*/
-int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int16_t *dlsch_llr,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint8_t beamforming_mode);
-
-/**
- \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dlsch_llr llr output
- @param dl_ch_mag Squared-magnitude of channel in each resource element position corresponding to allocation and weighted for mid-point in 16QAM constellation
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adjust Adjustment factor in RE for PBCH/PSS/SSS allocations
- @param llr128p pointer to pointer to symbol in dlsch_llr
- @param beamforming_mode beamforming mode
-*/
-
-int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
- int **rxdataF_comp,
- int32_t **sic_buffer,
- int **rho_i,
- short *dlsch_llr,
- uint8_t num_pdcch_symbols,
- uint16_t nb_rb,
- uint8_t subframe,
- uint16_t mod_order_0,
- uint32_t rb_alloc);
-
-void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int16_t *dlsch_llr,
- int32_t **dl_ch_mag,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- int16_t **llr32p,
- uint8_t beamforming_mode);
-/**
- \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dlsch_llr llr output
- @param dl_ch_mag Squared-magnitude of channel in each resource element position corresponding to allocation, weighted by first mid-point of 64-QAM constellation
- @param dl_ch_magb Squared-magnitude of channel in each resource element position corresponding to allocation, weighted by second mid-point of 64-QAM constellation
- @param symbol OFDM symbol index in sub-frame
- @param first_symbol_flag
- @param nb_rb number of RBs for this allocation
- @param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs)
- @param beamforming_mode beamforming mode
-*/
-void nr_dlsch_16qam_llr_SIC (NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **sic_buffer, //Q15
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t num_pdcch_symbols,
- int32_t **dl_ch_mag,
- uint16_t nb_rb,
- uint8_t subframe,
- uint16_t mod_order_0,
- uint32_t rb_alloc);
-
-void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **sic_buffer, //Q15
- int32_t **rho_i,
- int16_t *dlsch_llr,
- uint8_t num_pdcch_symbols,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint16_t nb_rb,
- uint8_t subframe,
- uint16_t mod_order_0,
- uint32_t rb_alloc);
-
-void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int16_t *dlsch_llr,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint32_t len,
- uint8_t first_symbol_flag,
- uint16_t nb_rb,
- uint32_t llr_offset,
- uint8_t beamforming_mode);
-
-
-/** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- uint8_t l,
- uint16_t nb_rb)
- \brief This function does the first stage of llr computation for SISO, by just extracting the pilots, PBCH and primary/secondary synchronization sequences.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param l symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
-*/
-
-void dlsch_siso(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- uint8_t l,
- uint16_t nb_rb);
-
-/** \fn dlsch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb)
- \brief This function does Alamouti combining on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param symbol Symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
-*/
-void dlsch_alamouti(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb);
-
-/** \fn dlsch_antcyc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb)
- \brief This function does antenna selection (based on antenna cycling pattern) on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals. Note that this is not LTE, it is just included for comparison purposes.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param symbol Symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
-*/
-void dlsch_antcyc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb);
-
-/** \fn dlsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int32_t **rho,
- int32_t **rho_i,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- uint8_t symbol,
- uint16_t nb_rb,
- uint8_t dual_stream_UE)
-
- \brief This function does maximal-ratio combining for dual-antenna receivers.
- @param frame_parms Frame descriptor structure
- @param rxdataF_comp Compensated channel output
- @param rxdataF_comp_i Compensated channel output for interference
- @param rho Cross correlation between spatial channels
- @param rho_i Cross correlation between signal and inteference channels
- @param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
- @param symbol Symbol in sub-frame
- @param nb_rb Number of RBs in this allocation
- @param dual_stream_UE Flag to indicate dual-stream detection
-*/
-void dlsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
- int32_t **rxdataF_comp,
- int32_t **rxdataF_comp_i,
- int32_t **rho,
- int32_t **rho_i,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- int32_t **dl_ch_mag_i,
- int32_t **dl_ch_magb_i,
- uint8_t symbol,
- uint16_t nb_rb,
- uint8_t dual_stream_UE);
-
-void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_PDSCH *lte_ue_pdsch_vars,
- int harq_pid,
- int round,
- unsigned char symbol,
- 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,
- uint16_t pmi,
- uint8_t *pmi_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- 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 pmi subband Precoding matrix indicator
- @param pmi_ext Extracted PMI for chosen RBs
- @param rb_alloc RB allocation vector
- @param symbol Symbol to extract
- @param subframe Subframe number
- @param vrb_type Flag to indicate distributed VRB type
- @param high_speed_flag
- @param frame_parms Pointer to frame descriptor
-*/
-/*uint16_t nr_dlsch_extract_rbs_single(int32_t **rxdataF,
- int32_t **dl_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_ch_estimates_ext,
- uint16_t pmi,
- uint8_t *pmi_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms);*/
-
-unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
- int **dl_ch_estimates,
- int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- unsigned short pmi,
- unsigned char *pmi_ext,
- unsigned char symbol,
- uint8_t pilots,
- unsigned short start_rb,
- unsigned short nb_pdsch_rb,
- unsigned char nr_tti_rx,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms);
-
-/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
- int32_t **dl_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_ch_estimates_ext,
- uint16_t pmi,
- uint8_t *pmi_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 dual 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 pmi subband Precoding matrix indicator
- @param pmi_ext Extracted PMI for chosen RBs
- @param rb_alloc RB allocation vector
- @param symbol Symbol to extract
- @param subframe Subframe index
- @param high_speed_flag
- @param frame_parms Pointer to frame descriptor
-*/
-unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF,
- int **dl_ch_estimates,
- int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- unsigned short pmi,
- unsigned char *pmi_ext,
- unsigned char symbol,
- uint8_t pilots,
- unsigned short start_rb,
- unsigned short nb_rb_pdsch,
- unsigned char nr_tti_rx,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms,
- MIMO_mode_t mimo_mode);
-
-/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
- int32_t **dl_bf_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_bf_ch_estimates_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- uint32_t high_speed_flag,
- 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_bf_ch_estimates Beamforming channel estimates of current slot
- @param rxdataF_ext FFT output for RBs in this allocation
- @param dl_bf_ch_estimates_ext Beamforming channel estimates for RBs in this allocation
- @param rb_alloc RB allocation vector
- @param symbol Symbol to extract
- @param subframe Subframe number
- @param high_speed_flag
- @param frame_parms Pointer to frame descriptor
-*/
-uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
- int32_t **dl_bf_ch_estimates,
- int32_t **rxdataF_ext,
- int32_t **dl_bf_ch_estimates_ext,
- uint32_t *rb_alloc,
- uint8_t symbol,
- uint8_t subframe,
- uint32_t high_speed_flag,
- NR_DL_FRAME_PARMS *frame_parms);
-
-/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
- @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
- @param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
- @param dl_ch_mag First Channel magnitudes (16QAM/64QAM)
- @param dl_ch_magb Second weighted Channel magnitudes (64QAM)
- @param rxdataF_comp Compensated received waveform
- @param rho Cross-correlation between two spatial channels on each RX antenna
- @param frame_parms Pointer to frame descriptor
- @param symbol Symbol on which to operate
- @param first_symbol_flag set to 1 on first DLSCH symbol
- @param mod_order Modulation order of allocation
- @param nb_rb Number of RBs in allocation
- @param output_shift Rescaling for compensated output (should be energy-normalizing)
- @param phy_measurements Pointer to UE PHY measurements
-*/
-void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
- int32_t **dl_ch_estimates_ext,
- int32_t **dl_ch_mag,
- int32_t **dl_ch_magb,
- int32_t **rxdataF_comp,
- int32_t **rho,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t symbol,
- uint8_t start_symbol,
- uint8_t first_symbol_flag,
- uint8_t mod_order,
- uint16_t nb_rb,
- uint8_t output_shift,
- PHY_NR_MEASUREMENTS *phy_measurements);
-
-void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- int **dl_ch_mag,
- int **dl_ch_magb,
- int **rxdataF_comp,
- int **rho,
- unsigned char n_tx,
- unsigned char n_rx,
- unsigned char mod_order,
- unsigned char output_shift,
- int length,
- int start_point);
-
-void nr_dlsch_deinterleaving(uint8_t symbol,
- uint8_t start_symbol,
- uint16_t L,
- uint16_t *llr,
- uint16_t *llr_deint,
- uint16_t nb_rb_pdsch);
-
-void dlsch_dual_stream_correlation(NR_DL_FRAME_PARMS *frame_parms,
- unsigned char symbol,
- unsigned short nb_rb,
- int **dl_ch_estimates_ext,
- int **dl_ch_estimates_ext_i,
- int **dl_ch_rho_ext,
- unsigned char output_shift);
-
-void dlsch_dual_stream_correlationTM34(NR_DL_FRAME_PARMS *frame_parms,
- unsigned char symbol,
- unsigned short nb_rb,
- int **dl_ch_estimates_ext,
- int **dl_ch_estimates_ext_i,
- int **dl_ch_rho_ext,
- unsigned char output_shift0,
- unsigned char output_shift1);
-//This function is used to compute multiplications in Hhermitian * H matrix
-void conjch0_mult_ch1(int *ch0,
- int *ch1,
- int32_t *ch0conj_ch1,
- unsigned short nb_rb,
- unsigned char output_shift0);
-
-void construct_HhH_elements(int *ch0conj_ch0,
- int *ch1conj_ch1,
- int *ch2conj_ch2,
- int *ch3conj_ch3,
- int *ch0conj_ch1,
- int *ch1conj_ch0,
- int *ch2conj_ch3,
- int *ch3conj_ch2,
- int32_t *after_mf_00,
- int32_t *after_mf_01,
- int32_t *after_mf_10,
- int32_t *after_mf_11,
- unsigned short nb_rb);
-
-void squared_matrix_element(int32_t *Hh_h_00,
- int32_t *Hh_h_00_sq,
- unsigned short nb_rb);
-
-void dlsch_channel_level_TM34_meas(int *ch00,
- int *ch01,
- int *ch10,
- int *ch11,
- int *avg_0,
- int *avg_1,
- unsigned short nb_rb);
-
-void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
- int32_t *median,
- int n_tx,
- int n_rx,
- int length,
- int start_point);
-
-void nr_dlsch_detection_mrc_core(int **rxdataF_comp,
- int **rxdataF_comp_i,
- int **rho,
- int **rho_i,
- int **dl_ch_mag,
- int **dl_ch_magb,
- int **dl_ch_mag_i,
- int **dl_ch_magb_i,
- unsigned char n_tx,
- unsigned char n_rx,
- int length,
- int start_point);
-
-void det_HhH(int32_t *after_mf_00,
- int32_t *after_mf_01,
- int32_t *after_mf_10,
- int32_t *after_mf_11,
- int32_t *det_fin_128,
- unsigned short nb_rb);
-
-void numer(int32_t *Hh_h_00_sq,
- int32_t *Hh_h_01_sq,
- int32_t *Hh_h_10_sq,
- int32_t *Hh_h_11_sq,
- int32_t *num_fin,
- unsigned short nb_rb);
-
-uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
- int *dl_ch_estimates_01,
- int *dl_ch_estimates_10,
- int *dl_ch_estimates_11,
- unsigned short nb_rb);
-
-void dlsch_channel_compensation_TM56(int **rxdataF_ext,
- int **dl_ch_estimates_ext,
- int **dl_ch_mag,
- int **dl_ch_magb,
- int **rxdataF_comp,
- unsigned char *pmi_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- PHY_NR_MEASUREMENTS *phy_measurements,
- int eNB_id,
- unsigned char symbol,
- unsigned char mod_order,
- unsigned short nb_rb,
- unsigned char output_shift,
- unsigned char dl_power_off);
-
-
-void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_PDSCH *lte_ue_pdsch_vars,
- PHY_NR_MEASUREMENTS *phy_measurements,
- int eNB_id,
- unsigned char symbol,
- unsigned char mod_order0,
- unsigned char mod_order1,
- int harq_pid,
- int round,
- MIMO_mode_t mimo_mode,
- unsigned short nb_rb,
- unsigned char output_shift0,
- unsigned char output_shift1);
-
-
-/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
- @param dl_ch_estimates_ext Channel estimates in allocated RBs
- @param frame_parms Pointer to frame descriptor
- @param avg Pointer to average signal strength
- @param pilots_flag Flag to indicate pilots in symbol
- @param nb_rb Number of allocated RBs
-*/
-void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- int32_t *avg,
- uint8_t symbol,
- uint32_t len,
- unsigned short nb_rb);
-
-
-void dlsch_channel_level_TM34(int **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- unsigned char *pmi_ext,
- int *avg_0,
- int *avg_1,
- uint8_t symbol,
- unsigned short nb_rb,
- MIMO_mode_t mimo_mode);
-
-
-void dlsch_channel_level_TM56(int32_t **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- unsigned char *pmi_ext,
- int32_t *avg,
- uint8_t symbol_mod,
- uint16_t nb_rb);
-
-void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- int32_t *avg,
- uint8_t pilots_flag,
- uint16_t nb_rb);
-
-void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t **dlsch_ue,
- uint8_t symbol,
- uint8_t start_symbol,
- uint16_t nb_rb);
-
-/** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several
- threads (on multi-core machines) corresponding to different HARQ processes. The routine first
- computes the segmentation information, followed by rate dematching and sub-block deinterleaving the of the
- received LLRs computed by dlsch_demodulation for each transport block segment. It then calls the
- turbo-decoding algorithm for each segment and stops after either after unsuccesful decoding of at least
- one segment or correct decoding of all segments. Only the segment CRCs are check for the moment, the
- overall CRC is ignored. Finally transport block reassembly is performed.
- @param phy_vars_ue Pointer to ue variables
- @param dlsch_llr Pointer to LLR values computed by dlsch_demodulation
- @param lte_frame_parms Pointer to frame descriptor
- @param dlsch Pointer to DLSCH descriptor
- @param frame Frame number
- @param subframe Subframe number
- @param num_pdcch_symbols Number of PDCCH symbols
- @param is_crnti indicates if PDSCH belongs to a CRNTI (necessary for parallelizing decoding threads)
- @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
- @returns 0 on success, 1 on unsuccessful decoding
-*/
-
-uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag);
-
-uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- int eNB_id,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag);
-
-void *nr_dlsch_decoding_2thread0(void *arg);
-
-void *nr_dlsch_decoding_2thread1(void *arg);
-
-void nr_dlsch_unscrambling(int16_t* llr,
- uint32_t size,
- uint8_t q,
- uint32_t Nid,
- uint32_t n_RNTI);
-
-uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t subframe,
- PDSCH_t dlsch_id,
- uint8_t eNB_id);
-
-/** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- - RB extraction (signal and channel estimates)
- - channel compensation (matched filtering)
- - RE extraction (pilot, PBCH, synch. signals)
- - antenna combining (MRC, Alamouti, cycling)
- - LLR computation
- This function supports TM1, 2, 3, 5, and 6.
- @param PHY_VARS_NR_UE Pointer to PHY variables
- @param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH)
- @param eNB_id eNb index (Nid1) 0,1,2
- @param eNB_id_i Interfering eNB index (Nid1) 0,1,2, or 3 in case of MU-MIMO IC receiver
- @param subframe Subframe number
- @param symbol Symbol on which to act (within sub-frame)
- @param first_symbol_flag set to 1 on first DLSCH symbol
- @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
- @param i_mod Modulation order of the interfering stream
-*/
-int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
- PDSCH_t type,
- uint8_t eNB_id,
- uint8_t eNB_id_i,
- uint32_t frame,
- uint8_t subframe,
- uint8_t symbol,
- uint8_t first_symbol_flag,
- RX_type_t rx_type,
- uint8_t i_mod,
- uint8_t harq_pid);
-
-/*! \brief Extract PSS and SSS resource elements
- @param phy_vars_ue Pointer to UE variables
- @param[out] pss_ext contain the PSS signals after the extraction
- @param[out] sss_ext contain the SSS signals after the extraction
- @returns 0 on success
-*/
-int pss_sss_extract(PHY_VARS_NR_UE *phy_vars_ue,
- int32_t pss_ext[4][72],
- int32_t sss_ext[4][72],
- uint8_t subframe);
-
-/*! \brief Extract only PSS resource elements
- @param phy_vars_ue Pointer to UE variables
- @param[out] pss_ext contain the PSS signals after the extraction
- @returns 0 on success
-*/
-int pss_only_extract(PHY_VARS_NR_UE *phy_vars_ue,
- int32_t pss_ext[4][72],
- uint8_t subframe);
-
-/*! \brief Extract only SSS resource elements
- @param phy_vars_ue Pointer to UE variables
- @param[out] sss_ext contain the SSS signals after the extraction
- @returns 0 on success
-*/
-int sss_only_extract(PHY_VARS_NR_UE *phy_vars_ue,
- int32_t sss_ext[4][72],
- uint8_t subframe);
-
-/*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix)
- @param phy_vars_ue Pointer to UE variables
- @param tot_metric Pointer to variable containing maximum metric under framing hypothesis (to be compared to other hypotheses
- @param flip_max Pointer to variable indicating if start of frame is in second have of RX buffer (i.e. PSS/SSS is flipped)
- @param phase_max Pointer to variable (0 ... 6) containing rought phase offset between PSS and SSS (can be used for carrier
- frequency adjustment. 0 means -pi/3, 6 means pi/3.
- @returns 0 on success
-*/
-int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uint8_t *phase_max);
-
-/*! \brief receiver for the PBCH
- \returns number of tx antennas or -1 if error
-*/
-int nr_rx_pbch( PHY_VARS_NR_UE *ue,
- UE_nr_rxtx_proc_t *proc,
- NR_UE_PBCH *nr_ue_pbch_vars,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t eNB_id,
- uint8_t i_ssb,
- MIMO_mode_t mimo_mode,
- uint32_t high_speed_flag);
-
-int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
- PHY_VARS_NR_UE *ue,
- int pbch_initial_symbol,
- runmode_t mode);
-
-uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t eNB_id,
- uint8_t pbch_phase);
-
-
-/*! \brief PBCH unscrambling
- This is similar to pbch_scrabling with the difference that inputs are signed s16s (llr values) and instead of flipping bits we change signs.
- \param frame_parms Pointer to frame descriptor
- \param llr Output of the demodulator
- \param length Length of the sequence
- \param frame_mod4 Frame number modulo 4*/
-void pbch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
- int8_t* llr,
- uint32_t length,
- uint8_t frame_mod4);
-
-
-void generate_64qam_table(void);
-void generate_16qam_table(void);
-void generate_qpsk_table(void);
-
-uint16_t extract_crc(uint8_t *dci,uint8_t DCI_LENGTH);
-
-/*! \brief LLR from two streams. This function takes two streams (qpsk modulated) and calculates the LLR, considering one stream as interference.
- \param stream0_in pointer to first stream0
- \param stream1_in pointer to first stream1
- \param stream0_out pointer to output stream
- \param rho01 pointer to correlation matrix
- \param length*/
-void qpsk_qpsk_TM3456(short *stream0_in,
- short *stream1_in,
- short *stream0_out,
- short *rho01,
- int length
- );
-
-/** \brief Attempt decoding of a particular DCI with given length and format.
- @param DCI_LENGTH length of DCI in bits
- @param DCI_FMT Format of DCI
- @param e e-sequence (soft bits)
- @param decoded_output Output of Viterbi decoder
-*/
-void dci_decoding(uint8_t DCI_LENGTH,
- uint8_t DCI_FMT,
- int8_t *e,
- uint8_t *decoded_output);
-
-/** \brief Do 36.213 DCI decoding procedure by searching different RNTI options and aggregation levels. Currently does
- not employ the complexity reducing procedure based on RNTI.
- @param phy_vars_ue UE variables
- @param dci_alloc Pointer to DCI_ALLOC_t array to store results for DLSCH/ULSCH programming
- @param do_common If 1 perform search in common search-space else ue-specific search-space
- @param eNB_id eNB Index on which to act
- @param subframe Index of subframe
- @returns bitmap of occupied CCE positions (i.e. those detected)
-*/
-uint16_t dci_decoding_procedure(PHY_VARS_NR_UE *phy_vars_ue,
- DCI_ALLOC_t *dci_alloc,
- int do_common,
- int16_t eNB_id,
- uint8_t subframe);
-
-uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_NR_UE *ue,
- DCI_ALLOC_t *dci_alloc,
- uint8_t DCIFormat,
- uint8_t agregationLevel,
- int16_t eNB_id,
- uint8_t subframe);
-
-uint16_t dci_decoding_procedure_emul(NR_UE_PDCCH **lte_ue_pdcch_vars,
- uint8_t num_ue_spec_dci,
- uint8_t num_common_dci,
- DCI_ALLOC_t *dci_alloc_tx,
- DCI_ALLOC_t *dci_alloc_rx,
- int16_t eNB_id);
-
-/** \brief Compute Q (modulation order) based on I_MCS PDSCH. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS */
-uint8_t get_Qm(uint8_t I_MCS);
-
-/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
- @param I_MCS */
-uint8_t get_Qm_ul(uint8_t I_MCS);
-
-/** \brief Compute I_TBS (transport-block size) based on I_MCS for PDSCH. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS */
-uint8_t get_I_TBS(uint8_t I_MCS);
-
-/** \brief Compute I_TBS (transport-block size) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
- @param I_MCS */
-unsigned char get_I_TBS_UL(unsigned char I_MCS);
-
-/** \brief Compute Q (modulation order) based on downlink I_MCS. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS
- @param nb_rb
- @return Transport block size */
-uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb);
-
-/** \brief Compute Q (modulation order) based on uplink I_MCS. Implements table 7.1.7.1-1 from 36.213.
- @param I_MCS
- @param nb_rb
- @return Transport block size */
-uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb);
-
-/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
- @param N_RB_DL number of PRB on DL
- @param indicator for even/odd slot
- @param vrb vrb index
- @param Ngap Gap indicator
-*/
-uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap);
-
-/* \brief Return prb for a given vrb index
- @param vrb_type VRB type (0=localized,1=distributed)
- @param rb_alloc_dci rballoc field from DCI
-*/
-uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci);
-
-
-/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
- @returns Transmission mode (1-7)
-*/
-uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
-
-
-/* \brief
- @param ra_header Header of resource allocation (0,1) (See sections 7.1.6.1/7.1.6.2 of 36.213 Rel8.6)
- @param rb_alloc Bitmap allocation from DCI (format 1,2)
- @returns number of physical resource blocks
-*/
-uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL);
-
-int get_G(NR_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode);
-
-int adjust_G(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
-int adjust_G2(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
-
-
-#ifndef modOrder
-#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
-#endif
-
-/** \fn uint8_t I_TBS2I_MCS(uint8_t I_TBS);
- \brief This function maps I_tbs to I_mcs according to Table 7.1.7.1-1 in 3GPP TS 36.213 V8.6.0. Where there is two supported modulation orders for the same I_TBS then either high or low modulation is chosen by changing the equality of the two first comparisons in the if-else statement.
- \param I_TBS Index of Transport Block Size
- \return I_MCS given I_TBS
-*/
-uint8_t I_TBS2I_MCS(uint8_t I_TBS);
-
-/** \fn uint8_t SE2I_TBS(float SE,
- uint8_t N_PRB,
- uint8_t symbPerRB);
- \brief This function maps a requested throughput in number of bits to I_tbs. The throughput is calculated as a function of modulation order, RB allocation and number of symbols per RB. The mapping orginates in the "Transport block size table" (Table 7.1.7.2.1-1 in 3GPP TS 36.213 V8.6.0)
- \param SE Spectral Efficiency (before casting to integer, multiply by 1024, remember to divide result by 1024!)
- \param N_PRB Number of PhysicalResourceBlocks allocated \sa lte_frame_parms->N_RB_DL
- \param symbPerRB Number of symbols per resource block allocated to this channel
- \return I_TBS given an SE and an N_PRB
-*/
-uint8_t SE2I_TBS(float SE,
- uint8_t N_PRB,
- uint8_t symbPerRB);
-/** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 36.211 v8.6.0. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence.
- @param frame_parms LTE DL Frame Parameters
- @param soundingrs_ul_config_dedicated Dynamic configuration from RRC during Connection Establishment
- @param txdataF pointer to the frequency domain TX signal
- @returns 0 on success*/
-int generate_srs(NR_DL_FRAME_PARMS *frame_parms,
- SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated,
- int *txdataF,
- int16_t amp,
- uint32_t subframe);
-
-
-/*!
- \brief This function is similar to generate_srs_tx but generates a conjugate sequence for channel estimation. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence.
- @param phy_vars_ue Pointer to PHY_VARS structure
- @param eNB_id Index of destination eNB for this SRS
- @param amp Linear amplitude of SRS
- @param subframe Index of subframe on which to act
- @returns 0 on success, -1 on error with message
-*/
-
-int32_t generate_srs_tx(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t eNB_id,
- int16_t amp,
- uint32_t subframe);
-
-/*!
- \brief This function generates the downlink reference signal for the PUSCH according to 36.211 v8.6.0. The DRS occuies the RS defined by rb_alloc and the symbols 2 and 8 for extended CP and 3 and 10 for normal CP.
-*/
-
-int32_t generate_drs_pusch(PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- uint8_t eNB_id,
- int16_t amp,
- uint32_t subframe,
- uint32_t first_rb,
- uint32_t nb_rb,
- uint8_t ant);
-
-/*!
- \brief This function initializes the Group Hopping, Sequence Hopping and nPRS sequences for PUCCH/PUSCH according to 36.211 v8.6.0. It should be called after configuration of UE (reception of SIB2/3) and initial configuration of eNB (or after reconfiguration of cell-specific parameters).
- @param frame_parms Pointer to a NR_DL_FRAME_PARMS structure (eNB or UE)*/
-void init_ul_hopping(NR_DL_FRAME_PARMS *frame_parms);
-
-
-/*!
- \brief This function implements the initialization of paging parameters for UE (See Section 7, 36.304).It must be called after setting IMSImod1024 during UE startup and after receiving SIB2
- @param ue Pointer to UE context
- @param defaultPagingCycle T from 36.304 (0=32,1=64,2=128,3=256)
- @param nB nB from 36.304 (0=4T,1=2T,2=T,3=T/2,4=T/4,5=T/8,6=T/16,7=T/32*/
-int init_ue_paging_info(PHY_VARS_NR_UE *ue, long defaultPagingCycle, long nB);
-
-int32_t compareints (const void * a, const void * b);
-
-
-void ulsch_modulation(int32_t **txdataF,
- int16_t amp,
- frame_t frame,
- uint32_t subframe,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_ULSCH_t *ulsch);
-
-
-
-
-
-
-int generate_ue_dlsch_params_from_dci(int frame,
- uint8_t subframe,
- void *dci_pdu,
- rnti_t rnti,
- DCI_format_t dci_format,
- NR_UE_PDCCH *pdcch_vars,
- NR_UE_PDSCH *pdsch_vars,
- NR_UE_DLSCH_t **dlsch,
- NR_DL_FRAME_PARMS *frame_parms,
- PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- uint16_t si_rnti,
- uint16_t ra_rnti,
- uint16_t p_rnti,
- uint8_t beamforming_mode,
- uint16_t tc_rnti);
-
-
-int generate_ue_ulsch_params_from_dci(void *dci_pdu,
- rnti_t rnti,
- uint8_t subframe,
- DCI_format_t dci_format,
- PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- uint16_t si_rnti,
- uint16_t ra_rnti,
- uint16_t p_rnti,
- uint16_t cba_rnti,
- uint8_t eNB_id,
- uint8_t use_srs);
-
-int32_t generate_ue_ulsch_params_from_rar(PHY_VARS_NR_UE *phy_vars_ue,
- UE_nr_rxtx_proc_t *proc,
- uint8_t eNB_id);
-double sinr_eff_cqi_calc(PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t eNB_id,
- uint8_t subframe);
-
-uint8_t sinr2cqi(double sinr,uint8_t trans_mode);
-
-
-int dump_dci(NR_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci);
-
-int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, char* buffer, int length, runmode_t mode, int input_level_dBm);
-
-void init_transport_channels(uint8_t);
-
-void generate_RIV_tables(void);
-
-/*!
- \brief Encoding of PUSCH/ACK/RI/ACK from 36-212.
- @param a Pointer to ulsch SDU
- @param frame_parms Pointer to Frame parameters
- @param ulsch Pointer to ulsch descriptor
- @param harq_pid HARQ process ID
- @param tmode Transmission mode (1-7)
- @param control_only_flag Generate PUSCH with control information only
- @param Nbundled Parameter for ACK/NAK bundling (36.213 Section 7.3)
-*/
-uint32_t ulsch_encoding(uint8_t *a,
- PHY_VARS_NR_UE *phy_vars_ue,
- uint8_t harq_pid,
- uint8_t eNB_id,
- uint8_t subframe_rx,
- uint8_t tmode,
- uint8_t control_only_flag,
- uint8_t Nbundled);
-
-void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL);
-
-void fill_CQI(NR_UE_ULSCH_t *ulsch,PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id, uint8_t harq_pid,int N_RB_DL, rnti_t rnti, uint8_t trans_mode,double sinr_eff);
-
-void reset_cba_uci(void *o);
-
-/** \brief This routine computes the subband PMI bitmap based on measurements (0,1,2,3 for rank 0 and 0,1 for rank 1) in the format needed for UCI
- @param meas pointer to measurements
- @param eNB_id eNB_id
- @param nb_subbands number of subbands
- @returns subband PMI bitmap
-*/
-uint16_t quantize_subband_pmi(PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands);
-
-int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb);
-
-uint16_t quantize_subband_pmi2(PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands);
-
-
-
-uint64_t cqi2hex(uint32_t cqi);
-
-uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
-
-
-/** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function
- @param N_RB_DL number of resource blocks
- @param mimo_mode
- @param pmi_alloc subband PMI bitmap
- @param rb resource block for which to extract PMI
- @returns subband PMI
-*/
-uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
-
-int get_nCCE_offset_l1(int *CCE_table,
- const unsigned char L,
- const int nCCE,
- const int common_dci,
- const unsigned short rnti,
- const unsigned char subframe);
-
-uint16_t get_nCCE(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
-
-uint16_t get_nquad(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
-
-uint8_t get_mi(NR_DL_FRAME_PARMS *frame,uint8_t subframe);
-
-uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe);
-
-uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
-
-void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi);
-
-void pdcch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
- uint8_t subframe,
- int8_t* llr,
- uint32_t length);
-
-
-
-void dlsch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
- int mbsfn_flag,
- NR_UE_DLSCH_t *dlsch,
- int G,
- int16_t* llr,
- uint8_t q,
- uint8_t Ns);
-
-void init_ncs_cell(NR_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]);
-
-void generate_pucch1x(int32_t **txdataF,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t ncs_cell[20][7],
- PUCCH_FMT_t fmt,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
- uint16_t n1_pucch,
- uint8_t shortened_format,
- uint8_t *payload,
- int16_t amp,
- uint8_t subframe);
-
-void generate_pucch2x(int32_t **txdataF,
- NR_DL_FRAME_PARMS *fp,
- uint8_t ncs_cell[20][7],
- PUCCH_FMT_t fmt,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
- uint16_t n2_pucch,
- uint8_t *payload,
- int A,
- int B2,
- int16_t amp,
- uint8_t subframe,
- uint16_t rnti);
-
-void generate_pucch3x(int32_t **txdataF,
- NR_DL_FRAME_PARMS *frame_parms,
- uint8_t ncs_cell[20][7],
- PUCCH_FMT_t fmt,
- PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
- uint16_t n3_pucch,
- uint8_t shortened_format,
- uint8_t *payload,
- int16_t amp,
- uint8_t subframe,
- uint16_t rnti);
-
-
-void init_ulsch_power_LUT(void);
-
-/*!
- \brief Check for PRACH TXop in subframe
- @param frame_parms Pointer to NR_DL_FRAME_PARMS
- @param frame frame index to check
- @param subframe subframe index to check
- @returns 0 on success
-*/
-int is_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t subframe);
-
-/*!
- \brief Generate PRACH waveform
- @param phy_vars_ue Pointer to ue top-level descriptor
- @param eNB_id Index of destination eNB
- @param subframe subframe index to operate on
- @param index of preamble (0-63)
- @param Nf System frame number
- @returns 0 on success
-
-*/
-int32_t generate_prach(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint16_t Nf);
-
-
-/*!
- \brief Helper for MAC, returns number of available PRACH in TDD for a particular configuration index
- @param frame_parms Pointer to NR_DL_FRAME_PARMS structure
- @returns 0-5 depending on number of available prach
-*/
-uint8_t get_num_prach_tdd(module_id_t Mod_id);
-
-/*!
- \brief Return the PRACH format as a function of the Configuration Index and Frame type.
- @param prach_ConfigIndex PRACH Configuration Index
- @param frame_type 0-FDD, 1-TDD
- @returns 0-1 accordingly
-*/
-uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type);
-
-uint16_t get_nr_prach_fmt(int prach_ConfigIndex,lte_frame_type_t frame_type, nr_frequency_range_e fr);
-
-/*!
- \brief Helper for MAC, returns frequency index of PRACH resource in TDD for a particular configuration index
- @param frame_parms Pointer to NR_DL_FRAME_PARMS structure
- @returns 0-5 depending on number of available prach
-*/
-uint8_t get_fid_prach_tdd(module_id_t Mod_id,uint8_t tdd_map_index);
-
-/*!
- \brief Comp ute DFT of PRACH ZC sequences. Used for generation of prach in UE and reception of PRACH in eNB.
- @param rootSequenceIndex PRACH root sequence
- #param prach_ConfigIndex PRACH Configuration Index
- @param zeroCorrelationZoneConfig PRACH ncs_config
- @param highSpeedFlat PRACH High-Speed Flag
- @param frame_type TDD/FDD flag
- @param Xu DFT output
-*/
-void compute_prach_seq(uint16_t rootSequenceIndex,
- uint8_t prach_ConfigIndex,
- uint8_t zeroCorrelationZoneConfig,
- uint8_t highSpeedFlag,
- lte_frame_type_t frame_type,
- uint32_t X_u[64][839]);
-
-
-void init_prach_tables(int N_ZC);
-
-void init_unscrambling_lut(void);
-void init_scrambling_lut(void);
-
-/*!
- \brief Return the status of MBSFN in this frame/subframe
- @param frame Frame index
- @param subframe Subframe index
- @param frame_parms Pointer to frame parameters
- @returns 1 if subframe is for MBSFN
-*/
-int is_pmch_subframe(frame_t frame, int subframe, NR_DL_FRAME_PARMS *frame_parms);
-
-uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots);
-
-uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode);
-
-uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB,
- NR_DL_FRAME_PARMS *lte_frame_parms,
- NR_UE_DLSCH_t *dlsch,
- uint8_t subframe,
- uint8_t num_pdcch_symbols);
-
-// DL power control functions
-double get_pa_dB(uint8_t pa);
-
-
-double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- NR_UE_DLSCH_t *dlsch_ue,
- uint8_t dl_power_off,
- uint8_t n_antenna_port);
-
-double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- PDSCH_CONFIG_COMMON *pdsch_config_common,
- uint8_t n_antenna_port,
- NR_UE_DLSCH_t *dlsch_ue,
- uint8_t dl_power_off);
-
-/*void compute_sqrt_RhoAoRhoB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
- PDSCH_CONFIG_COMMON *pdsch_config_common,
- uint8_t n_antenna_port,
- NR_UE_DLSCH_t *dlsch_ue);
-*/
-
-uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
- uint8_t prach_ConfigIndex,
- uint8_t n_ra_prboffset,
- uint8_t tdd_mapindex, uint16_t Nf);
-
-uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
-
-int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
- PDSCH_t type,
- unsigned char eNB_id,
- unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
- uint32_t frame,
- uint8_t nr_tti_rx,
- unsigned char symbol,
- unsigned char first_symbol_flag,
- RX_type_t rx_type,
- unsigned char i_mod,
- unsigned char harq_pid);
-
-uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) ;
-
-uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag);
-
-/**@}*/
-#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
index 2bc623a66c..3622e61b61 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c
@@ -35,12 +35,59 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
+int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
+
+ uint16_t i;
+ int16_t first_free_index=-1;
+
+ AssertFatal(gNB!=NULL,"gNB is null\n");
+ for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i);
+ AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i);
+ LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index);
+ if ((gNB->ulsch[i][0]->harq_mask >0) &&
+ (gNB->ulsch[i][0]->rnti==rnti)) return i;
+ else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
+ }
+ if (type == SEARCH_EXIST) return -1;
+ if (first_free_index != -1)
+ gNB->ulsch[first_free_index][0]->rnti = 0;
+ return first_free_index;
+}
+
+void nr_fill_ulsch(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot,
+ nfapi_nr_pusch_pdu_t *ulsch_pdu) {
+
+
+ int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
+ AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id);
+
+ NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0];
+ int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
+ ulsch->rnti = ulsch_pdu->rnti;
+ //ulsch->rnti_type;
+ ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid;
+
+ ulsch->harq_processes[harq_pid]->frame=frame;
+ ulsch->harq_processes[harq_pid]->slot=slot;
+ ulsch->harq_processes[harq_pid]->handled= 0;
+ ulsch->harq_processes[harq_pid]->status= NR_ACTIVE;
+ memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t));
+
+ LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
+
+}
+
void nr_ulsch_unscrambling(int16_t* llr,
- uint32_t size,
- uint8_t q,
- uint32_t Nid,
- uint32_t n_RNTI)
-{
+ uint32_t size,
+ uint8_t q,
+ uint32_t Nid,
+ uint32_t n_RNTI) {
+
uint8_t reset;
uint32_t x1, x2, s=0;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 6c6ff4fd05..09e57eaf9f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -218,13 +218,13 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
/// Nfapi ULSCH PDU
//nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
ulsch->harq_processes[i]->frame=0;
- ulsch->harq_processes[i]->subframe=0;
+ ulsch->harq_processes[i]->slot=0;
ulsch->harq_processes[i]->round=0;
ulsch->harq_processes[i]->TPC=0;
ulsch->harq_processes[i]->mimo_mode=0;
ulsch->harq_processes[i]->dci_alloc=0;
ulsch->harq_processes[i]->rar_alloc=0;
- ulsch->harq_processes[i]->status=0;
+ ulsch->harq_processes[i]->status=NR_SCH_IDLE;
ulsch->harq_processes[i]->subframe_scheduling_flag=0;
ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0;
ulsch->harq_processes[i]->phich_active=0;
@@ -420,7 +420,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
if (!frame%100)
- printf("K %d C %d Z %d\n", harq_process->K, harq_process->C, harq_process->Z);
+ printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
#endif
}
p_decParams->Z = harq_process->Z;
@@ -666,8 +666,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
ulsch->harq_mask &= ~(1 << harq_pid);
}
- // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
- // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
+ // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+ // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
harq_process->handled = 1;
ret = ulsch->max_ldpc_iterations + 1;
@@ -689,6 +689,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
+
// Reassembly of Transport block here
offset = 0;
Kr = harq_process->K;
@@ -713,10 +714,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#ifdef DEBUG_ULSCH_DECODING
LOG_I(PHY, "Decoder output (payload): \n");
- for (i = 0; i < harq_process->TBS / 8; i++) {
+ for (i = 0; i < harq_process->TBS ; i++) {
//harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
- printf("0x%02x",harq_process->b[i]);
+ printf("%02x",harq_process->b[i]);
}
#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 363b67960d..d1282a90e7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -222,7 +222,6 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
}
-
void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
@@ -230,9 +229,10 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms)
{
+
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx;
- uint8_t K_ptrs;
+ uint8_t K_ptrs = 0;
uint32_t rxF_ext_index = 0;
uint32_t ul_ch0_ext_index = 0;
uint32_t ul_ch0_index = 0;
@@ -259,8 +259,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
is_ptrs_symbol_flag = 0;
num_ptrs_symbols = 0;
- K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
-
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
@@ -313,7 +311,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
#ifdef DEBUG_RB_EXT
- printf("rxF_ext[%d] = %d, %d\n", rxF_ext_index, rxF_ext[rxF_ext_index], rxF_ext[rxF_ext_index+1]);
+ printf("rxF_ext[%d] = (%d,%d)\n", rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1]);
#endif
ul_ch0_ext_index++;
@@ -369,7 +367,6 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
nb_rb = (2*nb_rb)/3;
}
-
for (rb=0;rb=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
- for (aatx=0; aatxnb_antenna_ports_gNB; aatx++)
+ for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) {
for (aarx=0; aarxnb_antennas_rx; aarx++) {
//clear average level
avg128U = vdupq_n_s32(0);
@@ -486,8 +483,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
((int32_t*)&avg128U)[2] +
((int32_t*)&avg128U)[3] ) / (nb_rb*nre);
}
-
-
+ }
#endif
}
@@ -513,12 +509,12 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12];
printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift);
- printf("----------------Before compansation------------------\n");
+ printf("----------------Before compensation------------------\n");
- for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){
+ for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx+=2){
- printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]);
- printf("ul_ch[%d] = %d\n", prnt_idx, ul_ch[prnt_idx]);
+ printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]);
+ printf("ul_ch[%d] = (%d,%d)\n", prnt_idx>>1, ul_ch[prnt_idx],ul_ch[prnt_idx+1]);
}
@@ -706,7 +702,6 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
if (rho) {
-
for (aarx=0; aarxnb_antennas_rx; aarx++) {
rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12];
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12];
@@ -788,7 +783,6 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
#elif defined(__arm__)
-
unsigned short rb;
unsigned char aatx,aarx,symbol_mod,is_dmrs_symbol=0;
@@ -990,9 +984,9 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
printf("----------------After compansation------------------\n");
- for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){
+ for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx+=2){
- printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]);
+ printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]);
}
@@ -1005,9 +999,9 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
printf("----------------After computation------------------\n");
- for (print_idx=0;print_idx<12*nb_rb*2;print_idx++){
+ for (print_idx=0;print_idx<12*nb_rb*2;print_idx+=2){
- printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]);
+ printf("ch_mag[%d] = (%d,%d)\n", print_idx>>1, ch_mag[print_idx],ch_mag[print_idx+1]);
}
@@ -1023,16 +1017,16 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
unsigned char harq_pid)
{
- uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
+ uint8_t aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
uint32_t nb_re_pusch, bwp_start_subcarrier;
uint8_t L_ptrs = 0; // PTRS parameter
int avgs;
int avg[4];
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu;
+ uint8_t nodata_dmrs = 1; // FIXME to be properly configured from fapi
dmrs_symbol_flag = 0;
- first_symbol_flag = 0;
gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0;
if(symbol == rel15_ul->start_symbol_index){
@@ -1040,7 +1034,6 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
gNB->pusch_vars[UE_id]->dmrs_symbol = 0;
gNB->pusch_vars[UE_id]->cl_done = 0;
gNB->pusch_vars[UE_id]->ptrs_symbols = 0;
- first_symbol_flag = 1;
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
@@ -1058,7 +1051,12 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
if (dmrs_symbol_flag == 1){
- nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8);
+ if (((rel15_ul->ul_dmrs_symb_pos)>>((symbol+1)%frame_parms->symbols_per_slot))&0x01)
+ AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
+ if (nodata_dmrs)
+ nb_re_pusch = 0;
+ else
+ nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8);
gNB->pusch_vars[UE_id]->dmrs_symbol = symbol;
} else {
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
@@ -1086,75 +1084,81 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
//--------------------- RBs extraction ---------------------
//----------------------------------------------------------
- start_meas(&gNB->ulsch_rbs_extraction_stats);
- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
- gNB->pusch_vars[UE_id],
- symbol,
- dmrs_symbol_flag,
- rel15_ul,
- frame_parms);
- stop_meas(&gNB->ulsch_rbs_extraction_stats);
+ if (nb_re_pusch > 0) {
- nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- frame_parms,
- gNB->ulsch[UE_id],
- symbol,
- dmrs_symbol_flag,
- rel15_ul->rb_size,
- rel15_ul->dmrs_config_type);
-
-
- if (first_symbol_flag==1) {
-
- nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- frame_parms,
- avg,
- symbol,
- nb_re_pusch,
- rel15_ul->rb_size);
- avgs = 0;
-
- for (aatx=0;aatxnb_antennas_tx;aatx++)
- for (aarx=0;aarxnb_antennas_rx;aarx++)
- avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
-
- gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1;
-
- }
-
- start_meas(&gNB->ulsch_channel_compensation_stats);
- nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
- gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
- gNB->pusch_vars[UE_id]->ul_ch_mag0,
- gNB->pusch_vars[UE_id]->ul_ch_magb0,
- gNB->pusch_vars[UE_id]->rxdataF_comp,
- (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL,
- frame_parms,
+ start_meas(&gNB->ulsch_rbs_extraction_stats);
+ nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
+ gNB->pusch_vars[UE_id],
symbol,
dmrs_symbol_flag,
- rel15_ul->qam_mod_order,
- rel15_ul->rb_size,
- gNB->pusch_vars[UE_id]->log2_maxh);
- stop_meas(&gNB->ulsch_channel_compensation_stats);
+ rel15_ul,
+ frame_parms);
+ stop_meas(&gNB->ulsch_rbs_extraction_stats);
+
+ nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ frame_parms,
+ gNB->ulsch[UE_id],
+ symbol,
+ dmrs_symbol_flag,
+ rel15_ul->rb_size,
+ rel15_ul->dmrs_config_type);
+
+
+ if (gNB->pusch_vars[UE_id]->cl_done==0) {
+
+ nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ frame_parms,
+ avg,
+ symbol,
+ nb_re_pusch,
+ rel15_ul->rb_size);
+
+ avgs = 0;
+
+ for (aatx=0;aatxnb_antennas_tx;aatx++)
+ for (aarx=0;aarxnb_antennas_rx;aarx++)
+ avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+
+ gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1;
+ gNB->pusch_vars[UE_id]->cl_done = 1;
+ }
+
+ start_meas(&gNB->ulsch_channel_compensation_stats);
+ nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
+ gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ gNB->pusch_vars[UE_id]->ul_ch_mag0,
+ gNB->pusch_vars[UE_id]->ul_ch_magb0,
+ gNB->pusch_vars[UE_id]->rxdataF_comp,
+ (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL,
+ frame_parms,
+ symbol,
+ dmrs_symbol_flag,
+ rel15_ul->qam_mod_order,
+ rel15_ul->rb_size,
+ gNB->pusch_vars[UE_id]->log2_maxh);
+ stop_meas(&gNB->ulsch_channel_compensation_stats);
#ifdef NR_SC_FDMA
- nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
+ nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
//----------------------------------------------------------
//-------------------- LLRs computation --------------------
//----------------------------------------------------------
- start_meas(&gNB->ulsch_llr_stats);
- nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
- gNB->pusch_vars[UE_id]->ul_ch_mag0,
- gNB->pusch_vars[UE_id]->ul_ch_magb0,
- &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
- rel15_ul->rb_size,
- nb_re_pusch,
- symbol,
- rel15_ul->qam_mod_order);
- stop_meas(&gNB->ulsch_llr_stats);
+ start_meas(&gNB->ulsch_llr_stats);
+ AssertFatal(gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order+nb_re_pusch*rel15_ul->qam_mod_order < (8*((3*8*6144)+12)) , "Mysterious llr buffer size check");
+ nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
+ gNB->pusch_vars[UE_id]->ul_ch_mag0,
+ gNB->pusch_vars[UE_id]->ul_ch_magb0,
+ &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
+ rel15_ul->rb_size,
+ nb_re_pusch,
+ symbol,
+ rel15_ul->qam_mod_order);
+ stop_meas(&gNB->ulsch_llr_stats);
- gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol;
+ }
+
+ gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch;
}
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 82adf111d1..e17a549d8c 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -20,15 +20,15 @@
*/
/*! \file PHY/NR_TRANSPORT/pucch_rx.c
-* \brief Top-level routines for decoding the PUCCH physical channel
-* \author A. Mico Pereperez, Padarthi Naga Prasanth, Francesco Mani, Raymond Knopp
-* \date 2020
-* \version 0.2
-* \company Eurecom
-* \email:
-* \note
-* \warning
-*/
+ * \brief Top-level routines for decoding the PUCCH physical channel
+ * \author A. Mico Pereperez, Padarthi Naga Prasanth, Francesco Mani, Raymond Knopp
+ * \date 2020
+ * \version 0.2
+ * \company Eurecom
+ * \email:
+ * \note
+ * \warning
+ */
#include
#include
#include
@@ -44,7 +44,6 @@
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
@@ -191,7 +190,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int16_t x_n_re[nr_sequences][24],x_n_im[nr_sequences][24];
for(i=0;inr_of_symbols; l++){
double alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,pucch_pdu->initial_cyclic_shift,mcs[i],l,pucch_pdu->start_symbol_index,slot);
#ifdef DEBUG_NR_PUCCH_RX
@@ -201,14 +200,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
alpha=0.0;
for (n=0; n<12; n++){
x_n_re[i][(12*l)+n] = (int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))); // Re part of base sequence shifted by alpha
+ - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))); // Re part of base sequence shifted by alpha
x_n_im[i][(12*l)+n] =(int16_t)((int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
- + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))); // Im part of base sequence shifted by alpha
+ + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))); // Im part of base sequence shifted by alpha
#ifdef DEBUG_NR_PUCCH_RX
- printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d) %d,%d\n",
- u,v,alpha,l,n,x_n_re[i][(12*l)+n],x_n_im[i][(12*l)+n],
- (int32_t)(round(32767*cos(alpha*n))),
- (int32_t)(round(32767*sin(alpha*n))));
+ printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d) %d,%d\n",
+ u,v,alpha,l,n,x_n_re[i][(12*l)+n],x_n_im[i][(12*l)+n],
+ (int32_t)(round(32767*cos(alpha*n))),
+ (int32_t)(round(32767*sin(alpha*n))));
#endif
}
}
@@ -230,12 +229,12 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
r_re[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0];
r_im[(12*l)+n]=((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1];
- #ifdef DEBUG_NR_PUCCH_RX
- printf("\t [nr_generate_pucch0] mapping to RE \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
- frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size)+re_offset,
- l,n,((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0],
- ((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]);
- #endif
+#ifdef DEBUG_NR_PUCCH_RX
+ printf("\t [nr_generate_pucch0] mapping to RE \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
+ frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,(l2*frame_parms->ofdm_symbol_size)+re_offset,
+ l,n,((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[0],
+ ((int16_t *)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset])[1]);
+#endif
re_offset++;
if (re_offset>= frame_parms->ofdm_symbol_size)
re_offset-=frame_parms->ofdm_symbol_size;
@@ -300,7 +299,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
n2=0;
for (l=0;lnr_of_symbols;l++) {
- seq_index = (pucch_pdu->initial_cyclic_shift+
+ seq_index = (pucch_pdu->initial_cyclic_shift+
mcs[i]+
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
for (n=0;n<12;n++,n2+=2) {
@@ -327,7 +326,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
index=maxpos;
#endif
// first bit of bitmap for sr presence and second bit for acknack presence
- uci_pdu->pdu_bit_map = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
+ uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0
uci_pdu->ul_cqi = 0xff; // currently not valid
uci_pdu->timing_advance = 0xffff; // currently not valid
@@ -505,13 +504,13 @@ void nr_decode_pucch1( int32_t **rxdataF,
if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1
z_dmrs_re_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[0];
z_dmrs_im_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[1];
-// printf("%d\t%d\t%d\n",l,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
+ // printf("%d\t%d\t%d\n",l,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]);
#endif
-// printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
+ // printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]);
}
re_offset++;
@@ -530,7 +529,7 @@ void nr_decode_pucch1( int32_t **rxdataF,
l,lprime);
#endif
// y_n contains the complex value d multiplied by the sequence r_u_v
- if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
+ if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n",
@@ -548,18 +547,18 @@ void nr_decode_pucch1( int32_t **rxdataF,
}
else{
r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha
+ - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha
r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
- + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha
+ + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha
r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_re[n]))>>15);
r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_im[n]))>>15);
}
-// printf("symbol=%d\tr_u_rx_re=%d\tr_u_rx_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n], r_u_v_alpha_delta_dmrs_im[n]);
+ // printf("symbol=%d\tr_u_rx_re=%d\tr_u_rx_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n], r_u_v_alpha_delta_dmrs_im[n]);
// PUCCH sequence = DM-RS sequence multiplied by d(0)
-/* y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15)
- - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n)
- y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15)
- + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) */
+ /* y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15)
+ - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n)
+ y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15)
+ + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) */
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n",
u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]);
@@ -609,12 +608,12 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_im_temp;
-// printf("symbol=%d\tz_re_rx=%d\tz_im_rx=%d\t",l,(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+ // printf("symbol=%d\tz_re_rx=%d\tz_im_rx=%d\t",l,(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n",
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
@@ -624,15 +623,15 @@ void nr_decode_pucch1( int32_t **rxdataF,
#endif
// multiplying with conjugate of low papr sequence
z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp;
-/* if(z_re_temp<0){
- printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_re[n],z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
- }
- printf("z1_re_rx=%d\tz1_im_rx=%d\n",(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); */
+ /* if(z_re_temp<0){
+ printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_re[n],z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
+ }
+ printf("z1_re_rx=%d\tz1_im_rx=%d\n",(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); */
}
}
}
@@ -643,12 +642,12 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
-// printf("symbol=%d\tz_dmrs_re_rx=%d\tz_dmrs_im_rx=%d\t",l,(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+ // printf("symbol=%d\tz_dmrs_re_rx=%d\tz_dmrs_im_rx=%d\t",l,(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n",
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
@@ -658,17 +657,17 @@ void nr_decode_pucch1( int32_t **rxdataF,
#endif
//finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
-/* if(z_dmrs_re_temp<0){
- printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_dmrs_re[n],z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
- }*/
+ - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ /* if(z_dmrs_re_temp<0){
+ printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_dmrs_re[n],z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15));
+ }*/
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
-// printf("z1_dmrs_re_rx=%d\tz1_dmrs_im_rx=%d\n",(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
- /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
- z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
+ // printf("z1_dmrs_re_rx=%d\tz1_dmrs_im_rx=%d\n",(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
+ /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
+ z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
}
}
}
@@ -695,9 +694,9 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp;
#ifdef DEBUG_NR_PUCCH_RX
@@ -708,9 +707,9 @@ void nr_decode_pucch1( int32_t **rxdataF,
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif
z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1);
z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp;
z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp;
}
@@ -723,9 +722,9 @@ void nr_decode_pucch1( int32_t **rxdataF,
if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){
for (int n=0; n<12 ; n++) {
z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
#ifdef DEBUG_NR_PUCCH_RX
@@ -737,14 +736,14 @@ void nr_decode_pucch1( int32_t **rxdataF,
#endif
//finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays
z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15)
- - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
+ - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1);
z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp;
z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp;
- /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
- z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
+ /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n];
+ z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */
}
}
}
@@ -796,8 +795,8 @@ void nr_decode_pucch1( int32_t **rxdataF,
for(int n=0;n<12;n++){
y_n_re[n]=round(z_re_rx[l*12+n]/floor(nrofSymbols/4))+y_n_re[n];
y_n_im[n]=round(z_im_rx[l*12+n]/floor(nrofSymbols/4))+y_n_im[n];
- }
- }
+ }
+ }
else{
for(int n=0;n<12;n++){
y1_n_re[n]=round(z_re_rx[l*12+n]/round(nrofSymbols/4))+y1_n_re[n];
@@ -829,12 +828,12 @@ void nr_decode_pucch1( int32_t **rxdataF,
}
//Decoding QPSK or BPSK symbols to obtain payload bits
if(nr_bit==1){
- if((d_re+d_im)>0){
- *payload=0;
- }
- else{
- *payload=1;
- }
+ if((d_re+d_im)>0){
+ *payload=0;
+ }
+ else{
+ *payload=1;
+ }
}
else if(nr_bit==2){
if((d_re>0)&&(d_im>0)){
@@ -872,6 +871,9 @@ __m256i *pucch2_lut[9]={pucch2_3bit,
pucch2_10bit,
pucch2_11bit};
+__m64 pucch2_polar_4bit[16];
+__m128i pucch2_polar_llr_num_lut[256],pucch2_polar_llr_den_lut[256];
+
void init_pucch2_luts() {
uint32_t out;
@@ -880,7 +882,9 @@ void init_pucch2_luts() {
for (int b=3;b<12;b++) {
for (uint16_t i=0;i<(1< 0 ? -1 : 1;
@@ -949,6 +953,62 @@ void init_pucch2_luts() {
*lut_ip1 = _mm256_insert_epi16(*lut_ip1,bit,15);
}
}
+ for (uint16_t i=0;i<16;i++) {
+ __m64 *lut_i=&pucch2_polar_4bit[i];
+
+ bit = (i&0x1) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,0);
+ bit = (i&0x2) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,1);
+ bit = (i&0x4) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,2);
+ bit = (i&0x8) > 0 ? -1 : 1;
+ *lut_i = _mm_insert_pi16(*lut_i,bit,3);
+ }
+ for (int i=0;i<256;i++) {
+ __m128i *lut_num_i=&pucch2_polar_llr_num_lut[i];
+ __m128i *lut_den_i=&pucch2_polar_llr_den_lut[i];
+ bit = (i&0x1) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,0);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,0);
+
+ bit = (i&0x10) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,1);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,1);
+
+ bit = (i&0x2) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,2);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,2);
+
+ bit = (i&0x20) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,3);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,3);
+
+ bit = (i&0x4) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,4);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,4);
+
+ bit = (i&0x40) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,5);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,5);
+
+ bit = (i&0x8) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,6);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,6);
+
+ bit = (i&0x80) > 0 ? 0 : 1;
+ *lut_num_i = _mm_insert_epi16(*lut_num_i,bit,7);
+ *lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,7);
+ printf("i %d, lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
+ ((int16_t *)lut_num_i)[0],
+ ((int16_t *)lut_num_i)[1],
+ ((int16_t *)lut_num_i)[2],
+ ((int16_t *)lut_num_i)[3],
+ ((int16_t *)lut_num_i)[4],
+ ((int16_t *)lut_num_i)[5],
+ ((int16_t *)lut_num_i)[6],
+ ((int16_t *)lut_num_i)[7]);
+ }
}
@@ -961,13 +1021,15 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
//pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
+
+
AssertFatal(pucch_pdu->nr_of_symbols==1 || pucch_pdu->nr_of_symbols==2,
"Illegal number of symbols for PUCCH 2 %d\n",pucch_pdu->nr_of_symbols);
//extract pucch and dmrs first
- int l2=-1;
+ int l2=pucch_pdu->start_symbol_index;
int re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
if (re_offset>= frame_parms->ofdm_symbol_size)
re_offset-=frame_parms->ofdm_symbol_size;
@@ -984,6 +1046,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
int16_t r_im_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
int16_t rd_re_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
int16_t rd_im_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32)));
+ int16_t *r_re_ext_p,*r_im_ext_p,*rd_re_ext_p,*rd_im_ext_p;
int16_t *rp[Prx2];
__m64 dmrs_re,dmrs_im;
@@ -1000,156 +1063,166 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
for (int aa=0;aanr_of_symbols == 1) {
- AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size);
- // 24 PRBs contains 48x16-bit, so 6x8x16-bit
- for (int prb=0;prbprb_size;prb+=2) {
- for (int aa=0;aaprb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size);
+ // 24 PRBs contains 48x16-bit, so 6x8x16-bit
+ for (int prb=0;prbprb_size;prb+=2) {
+ for (int aa=0;aa (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext[aa][i],rd_im_ext[aa]);
+ for (int i=0;i<8;i++) printf("Ant %d PRB %d dmrs[%d] -> (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext_p[i],rd_im_ext_p[i]);
+ for (int i=0;i<16;i++) printf("Ant %d PRB %d data[%d] -> (%d,%d)\n",aa,prb+(i>>3),i,r_re_ext_p[i],r_im_ext_p[i]);
#endif
- } // aa
- } // prb
+ rp[aa]+=48;
+ } // aa
+ } // prb
- // first compute DMRS component
- uint32_t x1, x2, s=0;
- x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
+ // first compute DMRS component
+ uint32_t x1, x2, s=0;
+ x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause
#ifdef DEBUG_NR_PUCCH_RX
- printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n",
- slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id);
+ printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n",
+ slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id);
#endif
- s = lte_gold_generic(&x1, &x2, 1);
+ s = lte_gold_generic(&x1, &x2, 1);
+ for (int group=0;group>=5;
+ corr32_im[group][aa]>>=5;
#ifdef DEBUG_NR_PUCCH_RX
- printf("Group %d: rd ((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",
- group,
- rd_re_ext[aa][4],rd_im_ext[aa][4],
- rd_re_ext[aa][5],rd_im_ext[aa][5],
- rd_re_ext[aa][6],rd_im_ext[aa][6],
- rd_re_ext[aa][7],rd_im_ext[aa][7]);
+ printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[group][aa],corr32_im[group][aa]);
#endif
- corr32_re[group][aa]+=(rd_re_ext[aa][4]*((int16_t*)&dmrs_re)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_im)[0]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][4]*((int16_t*)&dmrs_im)[0] + rd_im_ext[aa][4]*((int16_t*)&dmrs_re)[0]);
- corr32_re[group][aa]+=(rd_re_ext[aa][5]*((int16_t*)&dmrs_re)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_im)[1]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][5]*((int16_t*)&dmrs_im)[1] + rd_im_ext[aa][5]*((int16_t*)&dmrs_re)[1]);
- corr32_re[group][aa]+=(rd_re_ext[aa][6]*((int16_t*)&dmrs_re)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_im)[2]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][6]*((int16_t*)&dmrs_im)[2] + rd_im_ext[aa][6]*((int16_t*)&dmrs_re)[2]);
- corr32_re[group][aa]+=(rd_re_ext[aa][7]*((int16_t*)&dmrs_re)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_im)[3]);
- corr32_im[group][aa]+=(-rd_re_ext[aa][7]*((int16_t*)&dmrs_im)[3] + rd_im_ext[aa][7]*((int16_t*)&dmrs_re)[3]);
- corr32_re[group][aa]>>=5;
- corr32_im[group][aa]>>=5;
-#ifdef DEBUG_NR_PUCCH_RX
- printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[group][aa],corr32_im[group][aa]);
-#endif
- } //aa
+ } //aa
- if ((group&3) == 3) s = lte_gold_generic(&x1, &x2, 0);
- } // group
+ if ((group&1) == 1) s = lte_gold_generic(&x1, &x2, 0);
+ } // group
}
else { // 2 symbol case
- AssertFatal(1==0, "Fill in 2 symbol PUCCH2 case\n");
+ AssertFatal(1==0, "Fill in 2 symbol PUCCH2 case\n");
}
uint32_t x1, x2, s=0;
@@ -1174,47 +1247,47 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
for (int aa=0;aabit_len_csi_part1 + pucch_pdu->bit_len_csi_part2 == 0,"no csi for now\n");
- AssertFatal((pucch_pdu->bit_len_harq+pucch_pdu->sr_flag > 2 ) && (pucch_pdu->bit_len_harq+pucch_pdu->sr_flag < 12),"illegal length (%d,%d)\n",pucch_pdu->bit_len_harq,pucch_pdu->sr_flag);
- int nb_bit = pucch_pdu->bit_len_harq+pucch_pdu->sr_flag;
- __m256i *rp_re[Prx2];
- __m256i *rp2_re[Prx2];
- __m256i *rp_im[Prx2];
- __m256i *rp2_im[Prx2];
- for (int aa=0;aa>1],
- ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[1+(i>>1)]);
- }
printf("\n");
#endif
- // do complex correlation
- for (int aa=0;aa corr) {
- corr = corr_tmp;
- cw_ML=cw;
- }
}
- uint8_t corr_dB = dB_fixed64((uint64_t)corr);
- LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
- uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq;
+ int nb_bit = pucch_pdu->bit_len_harq+pucch_pdu->sr_flag+pucch_pdu->bit_len_csi_part1+pucch_pdu->bit_len_csi_part2;
+ AssertFatal(nb_bit > 2 && nb_bit< 65,"illegal length (%d : %d,%d,%d,%d)\n",nb_bit,pucch_pdu->bit_len_harq,pucch_pdu->sr_flag,pucch_pdu->bit_len_csi_part1,pucch_pdu->bit_len_csi_part2);
-
- int harq_bytes=pucch_pdu->bit_len_harq>>3;
- if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
- uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes);
- uci_pdu->harq.harq_crc = 2;
- for (int i=0;iharq.harq_payload[i] = cw_ML & 255;
- cw_ML>>=8;
+ uint64_t decodedPayload[2];
+ uint8_t corr_dB;
+ int decoderState=2;
+ if (nb_bit < 12) { // short blocklength case
+ __m256i *rp_re[Prx2];
+ __m256i *rp2_re[Prx2];
+ __m256i *rp_im[Prx2];
+ __m256i *rp2_im[Prx2];
+ for (int aa=0;aa>1],
+ ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[1+(i>>1)]);
+ }
+ printf("\n");
+#endif
+ // do complex correlation
+ for (int aa=0;aa (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
+ ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3],
+ ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7],
+ ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11],
+ ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]);
+ printf("prod_im[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa,
+ ((int16_t*)&prod_im[aa])[0],((int16_t*)&prod_im[aa])[1],((int16_t*)&prod_im[aa])[2],((int16_t*)&prod_im[aa])[3],
+ ((int16_t*)&prod_im[aa])[4],((int16_t*)&prod_im[aa])[5],((int16_t*)&prod_im[aa])[6],((int16_t*)&prod_im[aa])[7],
+ ((int16_t*)&prod_im[aa])[8],((int16_t*)&prod_im[aa])[9],((int16_t*)&prod_im[aa])[10],((int16_t*)&prod_im[aa])[11],
+ ((int16_t*)&prod_im[aa])[12],((int16_t*)&prod_im[aa])[13],((int16_t*)&prod_im[aa])[14],((int16_t*)&prod_im[aa])[15]);
+
+#endif
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15
+ prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]);
+ }
+ int64_t corr_re=0,corr_im=0;
+
+ int64_t corr_tmp = 0;
+ for (int aa=0;aa corr) {
+ corr = corr_tmp;
+ cw_ML=cw;
+ }
+ }
+ corr_dB = dB_fixed64((uint64_t)corr);
+ LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
+ decodedPayload[0]=(uint64_t)cw_ML;
+ }
+ else { // polar coded case
+
+ t_nrPolar_params *currentPtr = nr_polar_params(2,nb_bit,pucch_pdu->prb_size,1,&gNB->uci_polarParams);
+ __m64 *rp_re[Prx2];
+ __m64 *rp2_re[Prx2];
+ __m64 *rp_im[Prx2];
+ __m64 *rp2_im[Prx2];
+ __m128i llrs[pucch_pdu->prb_size*2];
+
+ for (int aa=0;aa>1]);
+ }
+ printf("\n");
+ }
+#endif
+
+ // non-coherent LLR computation on groups of 4 REs (half-PRBs)
+ int32_t corr_re,corr_im,corr_tmp;
+ __m128i corr16,llr_num,llr_den;
+ uint64_t corr = 0;
+
+ for (int half_prb=0;half_prb<(2*pucch_pdu->prb_size);half_prb++) {
+ llr_num=_mm_set1_epi16(0);llr_den=_mm_set1_epi16(0);
+ for (int cw=0;cw<256;cw++) {
+ corr_tmp=0;
+ for (int aa=0;aa>4],rp_im[aa][half_prb])),5);
+ prod_im[aa] = _mm_srai_pi16(_mm_subs_pi16(_mm_mullo_pi16(pucch2_polar_4bit[cw&15],rp2_im[aa][half_prb]),
+ _mm_mullo_pi16(pucch2_polar_4bit[cw>>4],rp2_re[aa][half_prb])),5);
+ prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1
+ prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]);
+ prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1+2+3
+ prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]);
+
+ // this is for UL CQI measurement
+ if (cw==0) corr += ((int64_t)corr32_re[half_prb>>2][aa]*corr32_re[half_prb>>2][aa])+
+ ((int64_t)corr32_im[half_prb>>2][aa]*corr32_im[half_prb>>2][aa]);
+
+
+ corr_re = ( corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_re[aa]))[0]);
+ corr_im = ( corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_im[aa]))[0]);
+ corr_tmp += corr_re*corr_re + corr_im*corr_im;
+ /*
+ LOG_D(PHY,"pucch2 half_prb %d cw %d (%d,%d) aa %d: (%d,%d,%d,%d,%d,%d,%d,%d)x(%d,%d,%d,%d,%d,%d,%d,%d) (%d,%d)+(%d,%d) = (%d,%d) => %d\n",
+ half_prb,cw,cw&15,cw>>4,aa,
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[0],((int16_t*)&pucch2_polar_4bit[cw>>4])[0],
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[1],((int16_t*)&pucch2_polar_4bit[cw>>4])[1],
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[2],((int16_t*)&pucch2_polar_4bit[cw>>4])[2],
+ ((int16_t*)&pucch2_polar_4bit[cw&15])[3],((int16_t*)&pucch2_polar_4bit[cw>>4])[3],
+ ((int16_t*)&rp_re[aa][half_prb])[0],((int16_t*)&rp_im[aa][half_prb])[0],
+ ((int16_t*)&rp_re[aa][half_prb])[1],((int16_t*)&rp_im[aa][half_prb])[1],
+ ((int16_t*)&rp_re[aa][half_prb])[2],((int16_t*)&rp_im[aa][half_prb])[2],
+ ((int16_t*)&rp_re[aa][half_prb])[3],((int16_t*)&rp_im[aa][half_prb])[3],
+ corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2),corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2),
+ ((int16_t*)(&prod_re[aa]))[0],
+ ((int16_t*)(&prod_im[aa]))[0],
+ corr_re,
+ corr_im,
+ corr_tmp);
+ */
+ }
+ corr16 = _mm_set1_epi16((int16_t)(corr_tmp>>8));
+ /*
+ LOG_D(PHY,"half_prb %d cw %d corr16 %d\n",half_prb,cw,corr_tmp>>8);
+ */
+ llr_num = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_num_lut[cw]),llr_num);
+ llr_den = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_den_lut[cw]),llr_den);
+ /*
+ LOG_D(PHY,"lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[0],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[1],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[2],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[3],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[4],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[5],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[6],
+ ((int16_t*)&pucch2_polar_llr_num_lut[cw])[7]);
+
+ LOG_D(PHY,"llr_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ ((int16_t*)&llr_num)[0],
+ ((int16_t*)&llr_num)[1],
+ ((int16_t*)&llr_num)[2],
+ ((int16_t*)&llr_num)[3],
+ ((int16_t*)&llr_num)[4],
+ ((int16_t*)&llr_num)[5],
+ ((int16_t*)&llr_num)[6],
+ ((int16_t*)&llr_num)[7]);
+ LOG_D(PHY,"llr_den (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ ((int16_t*)&llr_den)[0],
+ ((int16_t*)&llr_den)[1],
+ ((int16_t*)&llr_den)[2],
+ ((int16_t*)&llr_den)[3],
+ ((int16_t*)&llr_den)[4],
+ ((int16_t*)&llr_den)[5],
+ ((int16_t*)&llr_den)[6],
+ ((int16_t*)&llr_den)[7]);
+ */
+ }
+ // compute llrs
+ llrs[half_prb] = _mm_subs_epi16(llr_num,llr_den);
+ LOG_D(PHY,"llrs[%d] : (%d,%d,%d,%d,%d,%d,%d,%d)\n",
+ half_prb,
+ ((int16_t*)&llrs[half_prb])[0],
+ ((int16_t*)&llrs[half_prb])[1],
+ ((int16_t*)&llrs[half_prb])[2],
+ ((int16_t*)&llrs[half_prb])[3],
+ ((int16_t*)&llrs[half_prb])[4],
+ ((int16_t*)&llrs[half_prb])[5],
+ ((int16_t*)&llrs[half_prb])[6],
+ ((int16_t*)&llrs[half_prb])[7]);
+ } // half_prb
+ // run polar decoder on llrs
+ decoderState = polar_decoder_int16((int16_t*)llrs, decodedPayload, 0, currentPtr);
+ LOG_D(PHY,"UCI decoderState %d, payload[0] %llux\n",decoderState,(unsigned long long)decodedPayload[0]);
+ if (decoderState>0) decoderState=1;
+ corr_dB = dB_fixed64(corr);
+ LOG_D(PHY,"metric %d dB\n",corr_dB);
+ }
+ uci_pdu->harq.harq_bit_len = pucch_pdu->bit_len_harq;
+ uci_pdu->pduBitmap=0;
+ uci_pdu->rnti=pucch_pdu->rnti;
+ uci_pdu->handle=pucch_pdu->handle;
+ uci_pdu->pucch_format=0;
+ uci_pdu->ul_cqi=corr_dB;
+ // need to fill these field!
+ uci_pdu->timing_advance=31;
+ uci_pdu->rssi=0;
+ if (pucch_pdu->bit_len_harq>0) {
+ int harq_bytes=pucch_pdu->bit_len_harq>>3;
+ if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
+ uci_pdu->pduBitmap|=1;
+ uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes);
+ uci_pdu->harq.harq_crc = decoderState > 0 ? 1 : 0;
+ int i=0;
+ for (;iharq.harq_payload[i] = decodedPayload[0] & 255;
+ decodedPayload[0]>>=8;
+ }
+ uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_harq&7))-1);
+ decodedPayload[0] >>= pucch_pdu->bit_len_harq;
}
if (pucch_pdu->sr_flag == 1) {
+ uci_pdu->pduBitmap|=2;
uci_pdu->sr.sr_bit_len = 1;
uci_pdu->sr.sr_payload = malloc(1);
- uci_pdu->sr.sr_payload[0] = cw_ML;
+ uci_pdu->sr.sr_payload[0] = decodedPayload[0]&1;
+ decodedPayload[0] = decodedPayload[0]>>1;
}
+ // csi
+ if (pucch_pdu->bit_len_csi_part1>0) {
+ uci_pdu->pduBitmap|=4;
+ int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3;
+ if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++;
+ uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes);
+ uci_pdu->csi_part1.csi_part1_crc = decoderState > 0 ? 1 : 0;
+ int i=0;
+ for (;icsi_part1.csi_part1_payload[i] = decodedPayload[0] & 255;
+ decodedPayload[0]>>=8;
+ }
+ uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_csi_part1&7))-1);
+ decodedPayload[0] >>= pucch_pdu->bit_len_csi_part1;
+ }
+
+ if (pucch_pdu->bit_len_csi_part2>0) {
+ uci_pdu->pduBitmap|=8;
+ }
+
}
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
index 7f5872e885..b49443c03c 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
@@ -34,8 +34,9 @@
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
- module_id_t eNB_id,
- uint8_t subframe,
+ module_id_t gNB_id,
+ uint8_t frame,
+ uint8_t subframe,
unsigned char clear,
short coef)
{
@@ -59,8 +60,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
temp = 0;
for (aa=0; aanb_antennas_rx; aa++) {
- Re = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
- Im = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
+ Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
+ Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
@@ -104,17 +105,19 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
+ ue->prach_resources[gNB_id]->sync_frame = frame;
+ ue->prach_resources[gNB_id]->init_msg1 = 0;
}
else {
ue->UE_mode[0] = PUSCH;
}
}
- if ( ue->rx_offset < 0 )
- ue->rx_offset += frame_parms->samples_per_frame;
+ if (ue->rx_offset < 0)
+ ue->rx_offset += frame_parms->samples_per_frame;
- if ( ue->rx_offset >= frame_parms->samples_per_frame )
- ue->rx_offset -= frame_parms->samples_per_frame;
+ if (ue->rx_offset >= frame_parms->samples_per_frame)
+ ue->rx_offset -= frame_parms->samples_per_frame;
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index af06f9a98f..1837664391 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -75,6 +75,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
module_id_t eNB_id,
+ uint8_t frame,
uint8_t subframe,
unsigned char clear,
short coef);
@@ -90,6 +91,7 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
uint32_t rx_power_fil_dB,
uint8_t eNB_id);
-int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index);
+int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
+
#endif
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index aa1e2b5ade..860ca11d8c 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -55,8 +55,9 @@ void print_ints(char *s,int *x)
}
#endif
-int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index)
-{
+int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){
+
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
/*
if (ue->frame_parms.mode1_flag == 1)
@@ -75,9 +76,6 @@ int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index)
//(ue->frame_parms.pdsch_config_common.referenceSignalPower*10))/10));
}
-
-
-
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
unsigned int subframe_offset,
unsigned char N0_symbol,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index ef22b61260..7cde6e31c1 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -29,11 +29,15 @@
* \note
* \warning
*/
+
#ifdef USER_MODE
#include
#include
#include
#endif
+
+#include "executables/softmodem-common.h"
+
#include "nr_transport_proto_ue.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
#include "PHY/phy_extern_nr_ue.h"
@@ -799,20 +803,22 @@ void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms,
#ifdef NR_PDCCH_DCI_RUN
-void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot,
- int16_t *z, int16_t *z2,uint32_t length, uint16_t pdcch_DMRS_scrambling_id) {
+void nr_pdcch_unscrambling(int16_t *z,
+ uint16_t scrambling_RNTI,
+ uint32_t length,
+ uint16_t pdcch_DMRS_scrambling_id,
+ int16_t *z2) {
int i;
uint8_t reset;
uint32_t x1, x2, s = 0;
uint16_t n_id; //{0,1,...,65535}
- uint32_t n_rnti;
+ uint32_t rnti = (uint32_t) scrambling_RNTI;
reset = 1;
// x1 is set in first call to lte_gold_generic
- //do_common=1;
- n_id = pdcch_DMRS_scrambling_id;
- n_rnti = (uint32_t)crnti;
+ n_id = pdcch_DMRS_scrambling_id;
+ x2 = ((rnti<<16) + n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3
- x2 = (((1<<16)*n_rnti)+n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3
+ LOG_D(PHY,"PDCCH Unscrambling x2 %x : scrambling_RNTI %x\n", x2, rnti);
for (i = 0; i < length; i++) {
if ((i & 0x1f) == 0) {
@@ -840,38 +846,48 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
rel15 = &pdcch_vars->pdcch_config[i];
int dci_length = rel15->dci_length;
+ //int gNB_id = 0;
int16_t tmp_e[16*108];
+ rnti_t n_rnti;
for (int j=0;jnumber_of_candidates;j++) {
- LOG_D(PHY,"Trying DCI candidate %d, CCE %d (%d), L %d\n",j,rel15->CCE[j],rel15->CCE[j]*9*6*2,rel15->L[j]);
int CCEind = rel15->CCE[j];
int L = rel15->L[j];
uint64_t dci_estimation[2]= {0};
- const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, dci_length, L,1,&ue->polarList);
+ const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
- nr_pdcch_unscrambling(rel15->rnti,
- &ue->frame_parms,
- slot,
- &pdcch_vars->e_rx[CCEind*108],
- tmp_e,
- L*108,
- // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72,
- rel15->coreset.pdcch_dmrs_scrambling_id);
+ LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
+
+ nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
+
+ #ifdef DEBUG_DCI_DECODING
+ uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
+ for (int index_z = 0; index_z < 96; index_z++){
+ for (int i=0; i<9; i++) {
+ LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
+ }
+ }
+ #endif
uint16_t crc = polar_decoder_int16(tmp_e,
dci_estimation,
1,
currentPtrDCI);
- LOG_D(PHY,"Decoded crc %x\n",crc);
- if (crc == rel15->rnti) {
+
+ n_rnti = rel15->rnti;
+
+ if (crc == n_rnti) {
+ LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
dci_ind->SFN = frame;
dci_ind->slot = slot;
- dci_ind->dci_list[dci_ind->number_of_dcis].rnti = rel15->rnti;
+ dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format;
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
dci_ind->number_of_dcis++;
+ } else {
+ LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
}
}
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index e5cbc4e07a..8214bdca99 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -42,6 +42,7 @@
#include "SIMULATION/TOOLS/sim.h"
#include "executables/nr-uesoftmodem.h"
#include "PHY/CODING/nrLDPC_extern.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#define DEBUG_DLSCH_DECODING
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
@@ -214,16 +215,16 @@ void nr_dlsch_unscrambling(int16_t* llr,
}
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
- short *dlsch_llr,
- NR_DL_FRAME_PARMS *frame_parms,
- NR_UE_DLSCH_t *dlsch,
- NR_DL_UE_HARQ_t *harq_process,
- uint32_t frame,
- uint16_t nb_symb_sch,
- uint8_t nr_tti_rx,
- uint8_t harq_pid,
- uint8_t is_crnti,
- uint8_t llr8_flag)
+ short *dlsch_llr,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_UE_DLSCH_t *dlsch,
+ NR_DL_UE_HARQ_t *harq_process,
+ uint32_t frame,
+ uint16_t nb_symb_sch,
+ uint8_t nr_tti_rx,
+ uint8_t harq_pid,
+ uint8_t is_crnti,
+ uint8_t llr8_flag)
{
#if UE_TIMING_TRACE
@@ -263,7 +264,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t dmrs_Type = harq_process->dmrsConfigType;
AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type);
- uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4;
+ uint8_t nb_re_dmrs = 12;//(dmrs_Type==1)?6:4;
uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
@@ -317,7 +318,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
- harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, harq_process->Nl);
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
A = harq_process->TBS;
ret = dlsch->max_ldpc_iterations + 1;
@@ -326,7 +327,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
G = harq_process->G;
- LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
+ LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,A/8,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
if ((harq_process->R)<1024)
Coderate = (float) (harq_process->R) /(float) 1024;
@@ -801,8 +802,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
//nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
//uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
- uint8_t nb_re_dmrs = (dmrs_type==1)?6:4;
- uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos);
+ uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4;
+ uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos);
uint32_t i,j;
// int nbDlProcessing =0;
@@ -854,7 +855,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
- harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl);
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
A = harq_process->TBS;
@@ -1431,7 +1432,7 @@ void nr_dlsch_decoding_process(void *arg)
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
- harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl);
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
A = harq_process->TBS; //2072 for QPSK 1/3
@@ -1697,10 +1698,10 @@ void nr_dlsch_decoding_process(void *arg)
}
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
- (int8_t*)&pl[0],
- llrProcBuf,
- p_nrLDPC_procBuf,
- p_procTime);
+ (int8_t*)&pl[0],
+ llrProcBuf,
+ p_nrLDPC_procBuf,
+ p_procTime);
// Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index c704efdb1f..7f941e5567 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -30,6 +30,7 @@
*/
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "nr_transport_proto_ue.h"
//#include "SCHED/defs.h"
//#include "PHY/defs.h"
@@ -131,7 +132,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
unsigned short nb_rb = 0, round;
int avgs = 0;// rb;
- NR_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
+ NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
uint8_t beamforming_mode;
@@ -155,82 +156,90 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
uint16_t n_tx=1, n_rx=1;
int32_t median[16];
uint32_t len;
-
+
switch (type) {
case SI_PDSCH:
- pdsch_vars = &ue->pdsch_vars_SI[eNB_id];
+ pdsch_vars = ue->pdsch_vars_SI;
dlsch = &ue->dlsch_SI[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- beamforming_mode = 0;
+ beamforming_mode = 0;
break;
case RA_PDSCH:
- pdsch_vars = &ue->pdsch_vars_ra[eNB_id];
+ pdsch_vars = ue->pdsch_vars_ra;
dlsch = &ue->dlsch_ra[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- beamforming_mode = 0;
+ beamforming_mode = 0;
+
break;
case PDSCH:
pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]];
dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
+ beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id];
+ dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+ dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
- dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
- dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
-
- //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
- LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n",
- frame,nr_tti_rx,symbol,harq_pid,
- dlsch[0]->harq_processes[harq_pid]->status,
- dlsch[1]->harq_processes[harq_pid]->status);
+ //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
+ LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
- if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
- (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)){
- codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
- codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
+ if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){
+ codeword_TB0 = dlsch0_harq->codeword;
+ codeword_TB1 = dlsch1_harq->codeword;
dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
-#ifdef DEBUG_HARQ
- printf("[DEMOD] I am assuming both TBs are active\n");
-#endif
- }
- else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
- (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) {
- codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword;
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] I am assuming both TBs are active\n");
+ #endif
+
+ } else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) {
+ codeword_TB0 = dlsch0_harq->codeword;
+ codeword_TB1 = -1;
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
dlsch1_harq = NULL;
- codeword_TB1 = -1;
-#ifdef DEBUG_HARQ
- printf("[DEMOD] I am assuming only TB0 is active\n");
-#endif
- }
- else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) &&
- (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){
- codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
- dlsch0_harq = dlsch[1]->harq_processes[harq_pid];
- dlsch1_harq = NULL;
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] I am assuming only TB0 is active\n");
+ #endif
+
+ } else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){
codeword_TB0 = -1;
-#ifdef DEBUG_HARQ
- printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch0_harq->codeword);
-#endif
- }
- else {
- LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n",nr_tti_rx);
+ codeword_TB1 = dlsch1_harq->codeword;
+ dlsch0_harq = NULL;
+ dlsch1_harq = dlsch[1]->harq_processes[codeword_TB1];
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch1_harq->codeword);
+ #endif
+
+ AssertFatal(1 == 0, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n");
+
+ } else {
+ LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
return(-1);
}
- beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
- break;
- default:
- LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n",nr_tti_rx,type);
- return(-1);
- break;
+ break;
+
+ default:
+ AssertFatal(1 == 0, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type);
+ return(-1);
+ break;
+
}
-#ifdef DEBUG_HARQ
- printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
- printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
-#endif
+
+ if (dlsch0_harq == NULL)
+ AssertFatal(1 == 0, "Done\n");
+
+ dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
+ dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
+
+ #ifdef DEBUG_HARQ
+ printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
+ printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
+ #endif
start_rb = dlsch0_harq->start_rb;
nb_rb_pdsch = dlsch0_harq->nb_rb;
@@ -269,7 +278,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
return(-1);
}
-
if (dlsch0_harq->mimo_mode==NR_DUALSTREAM) {
DevAssert(dlsch1_harq);
}
@@ -363,7 +371,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
nr_tti_rx,
ue->high_speed_flag,
frame_parms);
-
+
} /*else if(beamforming_mode>7) {
LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
}*/
@@ -624,7 +632,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0
} */
}
- }
+ }
//printf("start compute LLR\n");
if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
@@ -655,19 +663,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
// -> // compute @pointer where llrs should filled for this ofdm-symbol
if (first_symbol_flag==1) pdsch_vars[eNB_id]->llr_offset[symbol-1] = 0;
- llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1];
- //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0];
- //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1];
- pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0];
- pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1];
- pllr_symbol_layer0 += llr_offset_symbol;
- pllr_symbol_layer1 += llr_offset_symbol;
- pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0];
- pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1];
- pllr_symbol_cw0 += llr_offset_symbol;
- pllr_symbol_cw1 += llr_offset_symbol;
-
- pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
+ llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1];
+ //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0];
+ //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1];
+ pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0];
+ pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1];
+ pllr_symbol_layer0 += llr_offset_symbol;
+ pllr_symbol_layer1 += llr_offset_symbol;
+ pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0];
+ pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1];
+ pllr_symbol_cw0 += llr_offset_symbol;
+ pllr_symbol_cw1 += llr_offset_symbol;
+
+ pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
/*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
symbol,
@@ -689,13 +697,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
case 2 :
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
nr_dlsch_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pllr_symbol_cw0,
- symbol,
- len,
- first_symbol_flag,
- nb_rb,
- beamforming_mode);
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pllr_symbol_cw0,
+ symbol,
+ len,
+ first_symbol_flag,
+ nb_rb,
+ beamforming_mode);
} else if (codeword_TB0 == -1){
@@ -964,46 +972,47 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
return(-1);
break;
}
+
if (dlsch1_harq) {
- switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
- case 2 :
- if (rx_type==rx_standard) {
- nr_dlsch_qpsk_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pllr_symbol_cw0,
- symbol,len,first_symbol_flag,nb_rb,
- beamforming_mode);
+ switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
+ case 2 :
+ if (rx_type==rx_standard) {
+ nr_dlsch_qpsk_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pllr_symbol_cw0,
+ symbol,len,first_symbol_flag,nb_rb,
+ beamforming_mode);
+ }
+ break;
+ case 4:
+ if (rx_type==rx_standard) {
+ nr_dlsch_16qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pdsch_vars[eNB_id]->llr[0],
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ symbol,len,first_symbol_flag,nb_rb,
+ pdsch_vars[eNB_id]->llr128,
+ beamforming_mode);
+ }
+ break;
+ case 6 :
+ if (rx_type==rx_standard) {
+ nr_dlsch_64qam_llr(frame_parms,
+ pdsch_vars[eNB_id]->rxdataF_comp0,
+ pllr_symbol_cw0,
+ pdsch_vars[eNB_id]->dl_ch_mag0,
+ pdsch_vars[eNB_id]->dl_ch_magb0,
+ symbol,len,first_symbol_flag,nb_rb,
+ pdsch_vars[eNB_id]->llr_offset[symbol],
+ beamforming_mode);
+ }
+ break;
+ default:
+ LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
+ return(-1);
+ break;
}
- break;
- case 4:
- if (rx_type==rx_standard) {
- nr_dlsch_16qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pdsch_vars[eNB_id]->llr[0],
- pdsch_vars[eNB_id]->dl_ch_mag0,
- symbol,len,first_symbol_flag,nb_rb,
- pdsch_vars[eNB_id]->llr128,
- beamforming_mode);
- }
- break;
- case 6 :
- if (rx_type==rx_standard) {
- nr_dlsch_64qam_llr(frame_parms,
- pdsch_vars[eNB_id]->rxdataF_comp0,
- pllr_symbol_cw0,
- pdsch_vars[eNB_id]->dl_ch_mag0,
- pdsch_vars[eNB_id]->dl_ch_magb0,
- symbol,len,first_symbol_flag,nb_rb,
- pdsch_vars[eNB_id]->llr_offset[symbol],
- beamforming_mode);
- }
- break;
- default:
- LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
- return(-1);
- break;
- }
- }
+ }
//nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index 61748a8e56..cee9a45fac 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -135,7 +135,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
- current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im+current_ssb->c_re;
+ current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
// generate a list of SSB structures
if (best_ssb == NULL)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 60306d8e53..612dc6283d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -505,7 +505,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
return(-1);
}
*/
- if (symbol==1) {
+ if (symbol==2) {
nr_pbch_quantize(pbch_e_rx,
(short *)&(nr_ue_pbch_vars->rxdataF_comp[0][symbol*240]),
144);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index 013b5ca4a6..e9e36f2c77 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -19,13 +19,13 @@
* contact@openairinterface.org
*/
-/*! \file PHY/LTE_TRANSPORT/prach_common.c
- * \brief Common routines for UE/eNB PRACH physical channel V8.6 2009-03
- * \author R. Knopp
- * \date 2011
- * \version 0.1
- * \company Eurecom
- * \email: knopp@eurecom.fr
+/*! \file PHY/NR_TRANSPORT/nr_prach.c
+ * \brief Routines for UE PRACH physical channel
+ * \author R. Knopp, G. Casati
+ * \date 2019
+ * \version 0.2
+ * \company Eurecom, Fraunhofer IIS
+ * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
@@ -35,16 +35,14 @@
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
-#include
#include "T.h"
-#include
-
-
+#define NR_PRACH_DEBUG 1
extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
@@ -60,77 +58,75 @@ extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
+extern const char *prachfmt[9];
+// Note:
+// - prach_fmt_id is an ID used to map to the corresponding PRACH format value in prachfmt
+// WIP todo:
+// - take prach start symbol into account
+// - idft for short sequence assumes we are transmitting starting in symbol 0 of a PRACH slot
+// - Assumes that PRACH SCS is same as PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
+// - Preamble index different from 0 is not detected by gNB
+int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
-
-
-
-
-
-
-int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf )
-{
-
- //lte_frame_type_t frame_type = ue->frame_parms.frame_type;
- //uint8_t tdd_config = ue->frame_parms.tdd_config;
NR_DL_FRAME_PARMS *fp=&ue->frame_parms;
- uint16_t rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
- uint8_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
- uint8_t Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
- uint8_t restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
- uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex;
- //uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index;
- int16_t *prachF = ue->prach_vars[eNB_id]->prachF;
+ fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config;
+ NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_id];
+ fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
+
+ uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found;
+ uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset = 0;
+ uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
- int16_t *prach = prach_tmp;
- int16_t *prach2;
- int16_t amp = ue->prach_vars[eNB_id]->amp;
- int16_t Ncp;
- uint16_t NCS=0;
- uint16_t *prach_root_sequence_map;
- uint16_t preamble_offset,preamble_shift;
- uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
- uint16_t d_start=-1,numshift;
+ int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu;
+ int32_t Xu_re, Xu_im, samp_count;
+ int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k;
+ //int restricted_Type;
- uint16_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range);
- //uint8_t Nsp=2;
- //uint8_t f_ra,t1_ra;
- uint16_t N_ZC = (prach_fmt<4)?839:139;
- uint8_t not_found;
- int16_t *Xu;
- uint16_t u;
- int32_t Xu_re,Xu_im;
- uint16_t offset,offset2;
- int prach_start;
- int i, prach_len=0;
- uint16_t first_nonzero_root_idx=0;
+ prach = prach_tmp;
+ prachF = ue->prach_vars[gNB_id]->prachF;
+ amp = ue->prach_vars[gNB_id]->amp;
+ Mod_id = ue->Mod_id;
+ prach_sequence_length = nrUE_config->prach_config.prach_sequence_length;
+ N_ZC = (prach_sequence_length == 0) ? 839:139;
+ mu = nrUE_config->prach_config.prach_sub_c_spacing;
+ restricted_set = prach_pdu->restricted_set;
+ rootSequenceIndex = prach_pdu->root_seq_id;
+ n_ra_prb = prach_pdu->freq_msg1;
+ NCS = prach_pdu->num_cs;
+ prach_fmt_id = prach_pdu->prach_format;
+ preamble_index = prach_resources->ra_PreambleIndex;
+ fd_occasion = 0;
+ prach_len = 0;
+ dftlen = 0;
+ first_nonzero_root_idx = 0;
+ kbar = 1;
+ K = 24;
+ k = 12*n_ra_prb - 6*fp->N_RB_UL;
+ //prachStartSymbol = prach_config_pdu->prach_start_symbol
+ //restricted_Type = 0;
-#if defined(OAI_USRP)
- prach_start = (ue->rx_offset+subframe*fp->samples_per_subframe-ue->hw_timing_advance-ue->N_TA_offset);
-#ifdef NR_PRACH_DEBUG
- LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
- prach_start,
- ue->rx_offset,
- ue->hw_timing_advance,
- ue->N_TA_offset);
-#endif
+ compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length,
+ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
+ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
+ ue->X_u);
+
+ if (mu == 0)
+ samp_count = fp->samples_per_subframe;
+ else
+ samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0;
+
+ #if defined (OAI_USRP)
+ prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset);
+ #else //normal case (simulation)
+ prach_start = slot*samp_count - ue->N_TA_offset;
+ #endif
if (prach_start<0)
- prach_start+=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
-
- if (prach_start>=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
- prach_start-=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME);
-
-#else //normal case (simulation)
- prach_start = subframe*fp->samples_per_subframe-ue->N_TA_offset;
- LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
- prach_start,
- ue->rx_offset,
- ue->hw_timing_advance,
- ue->N_TA_offset);
-
-#endif
+ prach_start += (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
+ if (prach_start >= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME))
+ prach_start -= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
// First compute physical root sequence
/************************************************************************
@@ -140,41 +136,19 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
* NOTE: Restricted set type B is not implemented
*************************************************************************/
- int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
- if (prach_fmt<3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt==3){
- if (restricted_set == 0) {
- NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config];
- } else {
- if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME
- if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME
- }
- }
- if (prach_fmt>3){
- NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config];
- }
-
- prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
-
- // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
- preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
+ prach_root_sequence_map = (prach_sequence_length == 0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
if (restricted_set == 0) {
+ // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
+ preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
// This is the \nu corresponding to the preamble index
preamble_shift = (NCS==0)? 0 : (preamble_index % (N_ZC/NCS));
preamble_shift *= NCS;
} else { // This is the high-speed case
-#ifdef NR_PRACH_DEBUG
- LOG_I(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config);
-#endif
+ #ifdef NR_PRACH_DEBUG
+ LOG_I(PHY, "PRACH [UE %d] High-speed mode, NCS %d\n", Mod_id, NCS);
+ #endif
not_found = 1;
preamble_index0 = preamble_index;
@@ -185,8 +159,9 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
while (not_found == 1) {
// current root depending on rootSequenceIndex and preamble_offset
int index = (rootSequenceIndex + preamble_offset) % N_ZC;
+ uint16_t n_group_ra = 0;
- if (prach_fmt<4) {
+ if (prach_fmt_id<4) {
// prach_root_sequence_map points to prach_root_sequence_map0_3
DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
} else {
@@ -196,8 +171,6 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
u = prach_root_sequence_map[index];
- uint16_t n_group_ra = 0;
-
if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
n_shift_ra = nr_du[u]/NCS;
d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
@@ -231,43 +204,49 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
}
// now generate PRACH signal
-#ifdef NR_PRACH_DEBUG
-
- if (NCS>0)
- LOG_D(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %x, prach_ConfigIndex %d, NCS %d (NCS_config %d, N_ZC/NCS %d): Preamble_offset %d, Preamble_shift %d\n",
- rootSequenceIndex,preamble_index,prach_fmt,prach_ConfigIndex,NCS,Ncs_config,N_ZC/NCS,
- preamble_offset,preamble_shift);
-
-#endif
+ #ifdef NR_PRACH_DEBUG
+ if (NCS>0)
+ LOG_I(PHY, "PRACH [UE %d] generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d\n", Mod_id,
+ rootSequenceIndex,
+ preamble_index,
+ prachfmt[prach_fmt_id],
+ NCS,
+ N_ZC,
+ preamble_offset,
+ preamble_shift);
+ #endif
// nsymb = (frame_parms->Ncp==0) ? 14:12;
- // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*subframe*nsymb;
- int kbar = 1;
- int K = 24;
- if (prach_fmt == 3) {
- K=4;
- kbar=10;
+ // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*slot*nsymb;
+
+ if (prach_sequence_length == 0 && prach_fmt_id == 3) {
+ K = 4;
+ kbar = 10;
+ } else if (prach_sequence_length == 1) {
+ K = 1;
+ kbar = 2;
}
- else if (prach_fmt > 3) {
- // Note: Assumes that PRACH SCS is same as PUSCH SCS
- K=1;
- kbar=2;
- }
- int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart;
- int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
- k = (12*n_ra_prb) - 6*fp->N_RB_UL;
+ if (k<0)
+ k += fp->ofdm_symbol_size;
- if (k<0) k+=fp->ofdm_symbol_size;
+ k *= K;
+ k += kbar;
+ k *= 2;
- k*=K;
- k+=kbar;
-
- LOG_D(PHY,"placing prach in position %d\n",k);
- k*=2;
+ LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d, preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id,
+ slot,
+ k,
+ n_ra_prb,
+ preamble_offset,
+ first_nonzero_root_idx);
Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx];
+ #if defined (PRACH_WRITE_OUTPUT_DEBUG)
+ LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1);
+ #endif
+
/********************************************************
*
* In function init_prach_tables:
@@ -282,10 +261,86 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe,
*
*********************************************************/
- AssertFatal(prach_fmt>3,"prach_fmt<=3: Fix this for other formats\n");
- int dftlen=2048;
- if (fp->N_RB_UL >= 137) dftlen=4096;
- if (fp->threequarter_fs==1) dftlen=(3*dftlen)/4;
+ if (fp->N_RB_UL <= 100)
+ AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL);
+ else if (fp->N_RB_UL < 137) {
+ if (fp->threequarter_fs == 0) {
+ //40 MHz @ 61.44 Ms/s
+ //50 MHz @ 61.44 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 49152;
+ if (prach_fmt_id == 3)
+ dftlen = 12288;
+ } // 839 sequence
+ else {
+ switch (mu){
+ case 1:
+ dftlen = 2048;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ }
+ } else { // threequarter sampling
+ // 40 MHz @ 46.08 Ms/s
+ if (prach_sequence_length == 0) {
+ AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n");
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 36864;
+ if (prach_fmt_id == 3)
+ dftlen = 9216;
+ } else {
+ switch (mu){
+ case 1:
+ dftlen = 1536;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ } // short format
+ } // 3/4 sampling
+ } // <=50 MHz BW
+ else if (fp->N_RB_UL <= 273) {
+ if (fp->threequarter_fs == 0) {
+ //80,90,100 MHz @ 122.88 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 98304;
+ if (prach_fmt_id == 3)
+ dftlen = 24576;
+ }
+ } else { // threequarter sampling
+ switch (mu){
+ case 1:
+ dftlen = 4096;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ }
+ } else {
+ AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n");
+ // 80 MHz @ 92.16 Ms/s
+ if (prach_sequence_length == 0) {
+ if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
+ dftlen = 73728;
+ if (prach_fmt_id == 3)
+ dftlen = 18432;
+ } else {
+ switch (mu){
+ case 1:
+ dftlen = 3072;
+ break;
+ default:
+ AssertFatal(1 == 0, "Shouldn't get here\n");
+ break;
+ }
+ }
+ }
for (offset=0,offset2=0; offset>15);
prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15;
prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15;
+
if (k==dftlen) k=0;
}
- switch (fp->N_RB_UL) {
- case 6:
- memset((void*)prachF,0,4*1536);
- break;
+ #if defined (PRACH_WRITE_OUTPUT_DEBUG)
+ LOG_M("prachF.m", "prachF", &prachF[1804], 1024, 1, 1);
+ LOG_M("Xu.m", "Xu", Xu, N_ZC, 1, 1);
+ #endif
- case 15:
- memset((void*)prachF,0,4*3072);
- break;
+ if (prach_sequence_length == 0) {
- case 25:
- memset((void*)prachF,0,4*6144);
- break;
+ AssertFatal(prach_fmt_id < 4, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id);
- case 50:
- memset((void*)prachF,0,4*12288);
- break;
+ switch (prach_fmt_id) {
+ case 0:
+ Ncp = 3168;
+ break;
+ case 1:
+ Ncp = 21024;
+ break;
+ case 2:
+ Ncp = 4688;
+ break;
+ case 3:
+ Ncp = 3168;
+ break;
+ }
- case 75:
- memset((void*)prachF,0,4*18432);
- break;
+ } else {
- case 100:
- if (fp->threequarter_fs == 0)
- memset((void*)prachF,0,4*24576);
- else
- memset((void*)prachF,0,4*18432);
- break;
+ //LOG_D(PHY, "PRACH [UE %d] in slot %d, format %d, msg1 frequency start %d startSymbol %d \n", Mod_id, slot, prachfmt[prach_fmt_id], n_ra_prb, prachStartSymbol);
- case 106:
- memset((void*)prachF,0,4*24576);
- break;
-}
-
- int mu = 1; // numerology is hardcoded. FIXME!!!
- switch (prach_fmt) {
- case 0:
- Ncp = 3168;
- break;
-
- case 1:
- Ncp = 2*21024;
- break;
-
- case 2:
- Ncp = 4688;
- break;
-
- case 3:
- Ncp = 3168;
- break;
-
- case 0xa1:
- Ncp = 288/(1<N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL);
else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s
- if (fp->threequarter_fs==0) { //61.44 Ms/s
+ if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s
Ncp<<=1;
// This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
- idft(IDFT_49152,prachF,prach2,1);
- // here we have |empty | Prach49152|
- memmove(prach,prach+(49152<<1),(Ncp<<3));
- // here we have |Prefix | Prach49152|
- prach_len = 49152+Ncp;
- dftlen=49152;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
+ idft(IDFT_49152,prachF,prach2,1);
+ // here we have |empty | Prach49152|
+ memmove(prach,prach+(49152<<1),(Ncp<<2));
+ // here we have |Prefix | Prach49152|
+ prach_len = 49152+Ncp;
+ } else if (prach_fmt_id == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
+ idft(IDFT_49152,prachF,prach2,1);
+ memmove(prach2+(49152<<1),prach2,(49152<<2));
+ // here we have |empty | Prach49152 | Prach49152|
+ memmove(prach,prach+(49152<<2),(Ncp<<2));
+ // here we have |Prefix | Prach49152 | Prach49152|
+ prach_len = (49152*2)+Ncp;
+ } else if (prach_fmt_id == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
+ idft(IDFT_49152,prachF,prach2,1);
+ memmove(prach2+(49152<<1),prach2,(49152<<2));
+ // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152
+ memmove(prach2+(49152<<2),prach2,(49152<<3));
+ // here we have |empty | Prach49152 | Prach49152| Prach49152 | Prach49152
+ memmove(prach,prach+(49152<<3),(Ncp<<2));
+ // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152
+ prach_len = (49152*4)+Ncp;
+ } else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
+ idft(IDFT_12288,prachF,prach2,1);
+ memmove(prach2+(12288<<1),prach2,(12288<<2));
+ // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
+ memmove(prach2+(12288<<2),prach2,(12288<<3));
+ // here we have |empty | Prach12288 | Prach12288| Prach12288 | Prach12288
+ memmove(prach,prach+(12288<<3),(Ncp<<2));
+ // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288
+ prach_len = (12288*4)+Ncp;
+ }
+ } else { // short PRACH sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ prach_len = (2048*2)+Ncp;
+ }
+ else prach_len = (2048*1)+Ncp;
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x2048
+ Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 |
+ memmove(prach2+(2048<<2),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 |
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 |
+ prach_len = (2048*4)+Ncp;
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x2048
+ Ncp+=32;
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<2),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<3),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 |
+ prach_len = (2048*6)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x2048
+ Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_2048,prachF,prach2,1);
+ // here we have |empty | Prach2048 |
+ memmove(prach2+(2048<<1),prach2,(2048<<2));
+ // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<2),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
+ memmove(prach2+(2048<<3),prach2,(2048<<3));
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
+ memmove(prach2+(2048<<1)*6,prach2,(2048<<2)*6);
+ // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
+ memmove(prach,prach+(2048<<1),(Ncp<<2));
+ // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
+ prach_len = (2048*12)+Ncp;
+ }
}
- else if (prach_fmt == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
- idft(IDFT_49152,prachF,prach2,1);
- memmove(prach2+(49152<<1),prach2,(49152<<2));
- // here we have |empty | Prach49152 | Prach49152|
- memmove(prach,prach+(49152<<2),(Ncp<<3));
- // here we have |Prefix | Prach49152 | Prach49152|
- prach_len = (49152*2)+Ncp;
- dftlen=49152;
- }
- else if (prach_fmt == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
- idft(IDFT_49152,prachF,prach2,1);
- memmove(prach2+(49152<<1),prach2,(49152<<2));
- // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152
- memmove(prach2+(49152<<2),prach2,(49152<<3));
- // here we have |empty | Prach49152 | Prach49152| Prach49152 | Prach49152
- memmove(prach,prach+(49152<<3),(Ncp<<3));
- // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152
- prach_len = (49152*4)+Ncp;
- dftlen=49152;
- }
- else if (prach_fmt == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
- idft(IDFT_12288,prachF,prach2,1);
- memmove(prach2+(12288<<1),prach2,(12288<<2));
- // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
- memmove(prach2+(12288<<2),prach2,(12288<<3));
- // here we have |empty | Prach12288 | Prach12288| Prach12288 | Prach12288
- memmove(prach,prach+(12288<<3),(Ncp<<3));
- // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288
- prach_len = (12288*4)+Ncp;
- dftlen=12288;
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- prach2 = prach+(Ncp<<1);
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- if (prach_fmt != 0xc0) {
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- prach_len = (2048*2)+Ncp;
- }
- else prach_len = (2048*1)+Ncp;
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x2048
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 |
- memmove(prach2+(2048<<2),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 |
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 |
- prach_len = (2048*4)+Ncp;
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x2048
- prach2 = prach+(Ncp<<1);
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
- memmove(prach2+(2048<<2),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
- memmove(prach2+((2048<<1)*3),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 |
- prach_len = (2048*6)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x2048
- idft(IDFT_2048,prachF,prach2,1);
- dftlen=2048;
- // here we have |empty | Prach2048 |
- memmove(prach2+(2048<<1),prach2,(2048<<2));
- // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
- memmove(prach2+(2048<<2),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048
- memmove(prach2+(2048<<3),prach2,(2048<<3));
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048
- memmove(prach2+(2048<<1)*6,prach2,(2048<<2)*6);
- // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
- memmove(prach,prach+(2048<<1),(Ncp<<2));
- // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
- prach_len = (2048*12)+Ncp;
- }
-
- }
- else { // 46.08 Ms/s
+ } else { // threequarter sampling @ 46.08 Ms/s
Ncp = (Ncp*3)/2;
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) {
- idft(IDFT_36864,prachF,prach2,1);
- dftlen=36864;
- // here we have |empty | Prach73728|
- memmove(prach,prach+(36864<<1),(Ncp<<2));
- // here we have |Prefix | Prach73728|
- prach_len = (36864*1)+Ncp;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) {
+ idft(IDFT_36864,prachF,prach2,1);
+ // here we have |empty | Prach73728|
+ memmove(prach,prach+(36864<<1),(Ncp<<2));
+ // here we have |Prefix | Prach73728|
+ prach_len = (36864*1)+Ncp;
+ } else if (prach_fmt_id == 1) {
+ idft(IDFT_36864,prachF,prach2,1);
+ memmove(prach2+(36864<<1),prach2,(36864<<2));
+ // here we have |empty | Prach73728 | Prach73728|
+ memmove(prach,prach+(36864<<2),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728|
+ prach_len = (36864*2)+Ncp;
+ } else if (prach_fmt_id == 2) {
+ idft(IDFT_36864,prachF,prach2,1);
+ memmove(prach2+(36864<<1),prach2,(36864<<2));
+ // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
+ memmove(prach2+(36864<<2),prach2,(36864<<3));
+ // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
+ memmove(prach,prach+(36864<<3),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
+ prach_len = (36864*4)+Ncp;
+ } else if (prach_fmt_id == 3) {
+ idft(IDFT_9216,prachF,prach2,1);
+ memmove(prach2+(9216<<1),prach2,(9216<<2));
+ // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216
+ memmove(prach2+(9216<<2),prach2,(9216<<3));
+ // here we have |empty | Prach9216 | Prach9216| Prach9216 | Prach9216
+ memmove(prach,prach+(9216<<3),(Ncp<<2));
+ // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216
+ prach_len = (9216*4)+Ncp;
+ }
+ } else { // short sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+
+ // here we have |empty | Prach1536 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ prach_len = (1536*2)+Ncp;
+ } else prach_len = (1536*1)+Ncp;
+
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
+
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x1536
+
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+ // here we have |empty | Prach1536 |
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 |
+ memmove(prach2+(1536<<2),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 |
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 |
+ prach_len = (1536*4)+Ncp;
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x1536
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+ // here we have |empty | Prach1536 |
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<2),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<3),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 |
+ prach_len = (1536*6)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x1536
+ Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_1536,prachF,prach2,1);
+ // here we have |empty | Prach1536 |
+ memmove(prach2+(1536<<1),prach2,(1536<<2));
+ // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<2),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
+ memmove(prach2+(1536<<3),prach2,(1536<<3));
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
+ memmove(prach2+(1536<<1)*6,prach2,(1536<<2)*6);
+ // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
+ memmove(prach,prach+(1536<<1),(Ncp<<2));
+ // here we have |Prefix | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
+ prach_len = (1536*12)+Ncp;
+ }
}
- else if (prach_fmt == 1) {
- idft(IDFT_36864,prachF,prach2,1);
- dftlen=36864;
- memmove(prach2+(36864<<1),prach2,(36864<<2));
- // here we have |empty | Prach73728 | Prach73728|
- memmove(prach,prach+(36864<<2),(Ncp<<2));
- // here we have |Prefix | Prach73728 | Prach73728|
- prach_len = (36864*2)+Ncp;
- }
- if (prach_fmt == 2) {
- idft(IDFT_36864,prachF,prach2,1);
- dftlen=36864;
- memmove(prach2+(36864<<1),prach2,(36864<<2));
- // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
- memmove(prach2+(36864<<2),prach2,(36864<<3));
- // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
- memmove(prach,prach+(36864<<3),(Ncp<<2));
- // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
- prach_len = (36864*4)+Ncp;
- }
- else if (prach_fmt == 3) {
- idft(IDFT_9216,prachF,prach2,1);
- dftlen=36864;
- memmove(prach2+(9216<<1),prach2,(9216<<2));
- // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216
- memmove(prach2+(9216<<2),prach2,(9216<<3));
- // here we have |empty | Prach9216 | Prach9216| Prach9216 | Prach9216
- memmove(prach,prach+(9216<<3),(Ncp<<2));
- // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216
- prach_len = (9216*4)+Ncp;
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- if (prach_fmt != 0xc0)
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
- prach_len = (1536*2)+Ncp;
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x1536
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 |
- memmove(prach2+(1536<<2),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 |
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 |
- prach_len = (1536*4)+Ncp;
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x1536
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
- memmove(prach2+(1536<<2),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
- memmove(prach2+((1536<<1)*3),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 |
- prach_len = (1536*6)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x1536
- idft(IDFT_1536,prachF,prach2,1);
- dftlen=1536;
- // here we have |empty | Prach1536 |
- memmove(prach2+(1536<<1),prach2,(1536<<2));
- // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
- memmove(prach2+(1536<<2),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536
- memmove(prach2+(1536<<3),prach2,(1536<<3));
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536
- memmove(prach2+(1536<<1)*6,prach2,(1536<<2)*6);
- // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
- memmove(prach,prach+(1536<<1),(Ncp<<2));
- // here we have |Prefix | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536|
- prach_len = (1536*12)+Ncp;
- }
}
- }
- else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
- if (fp->threequarter_fs==0) { //122.88 Ms/s
+ } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
+ if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s
Ncp<<=2;
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
- idft(IDFT_98304,prachF,prach2,1);
- dftlen=98304;
- // here we have |empty | Prach98304|
- memmove(prach,prach+(98304<<1),(Ncp<<2));
- // here we have |Prefix | Prach98304|
- prach_len = (98304*1)+Ncp;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
+ idft(IDFT_98304,prachF,prach2,1);
+ // here we have |empty | Prach98304|
+ memmove(prach,prach+(98304<<1),(Ncp<<2));
+ // here we have |Prefix | Prach98304|
+ prach_len = (98304*1)+Ncp;
+ } else if (prach_fmt_id == 1) {
+ idft(IDFT_98304,prachF,prach2,1);
+ memmove(prach2+(98304<<1),prach2,(98304<<2));
+ // here we have |empty | Prach98304 | Prach98304|
+ memmove(prach,prach+(98304<<2),(Ncp<<2));
+ // here we have |Prefix | Prach98304 | Prach98304|
+ prach_len = (98304*2)+Ncp;
+ } else if (prach_fmt_id == 2) {
+ idft(IDFT_98304,prachF,prach2,1);
+ memmove(prach2+(98304<<1),prach2,(98304<<2));
+ // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304
+ memmove(prach2+(98304<<2),prach2,(98304<<3));
+ // here we have |empty | Prach98304 | Prach98304| Prach98304 | Prach98304
+ memmove(prach,prach+(98304<<3),(Ncp<<2));
+ // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304
+ prach_len = (98304*4)+Ncp;
+ } else if (prach_fmt_id == 3) { // 4x6144, Ncp 3168
+ idft(IDFT_24576,prachF,prach2,1);
+ memmove(prach2+(24576<<1),prach2,(24576<<2));
+ // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576
+ memmove(prach2+(24576<<2),prach2,(24576<<3));
+ // here we have |empty | Prach24576 | Prach24576| Prach24576 | Prach24576
+ memmove(prach,prach+(24576<<3),(Ncp<<2));
+ // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576
+ prach_len = (24576*4)+Ncp;
+ }
+ } else { // short sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ prach_len = (4096*2)+Ncp;
+ } else prach_len = (4096*1)+Ncp;
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) |
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x4096
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 |
+ memmove(prach2+(4096<<2),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 |
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 |
+ prach_len = (4096*4)+Ncp;
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x4096
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<2),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<3),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 |
+ prach_len = (4096*6)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x4096
+ Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_4096,prachF,prach2,1);
+ // here we have |empty | Prach4096 |
+ memmove(prach2+(4096<<1),prach2,(4096<<2));
+ // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<2),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
+ memmove(prach2+(4096<<3),prach2,(4096<<3));
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
+ memmove(prach2+(4096<<1)*6,prach2,(4096<<2)*6);
+ // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
+ memmove(prach,prach+(4096<<1),(Ncp<<2));
+ // here we have |Prefix | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
+ prach_len = (4096*12)+Ncp;
+ }
}
- else if (prach_fmt == 1) {
- idft(IDFT_98304,prachF,prach2,1);
- dftlen=98304;
- memmove(prach2+(98304<<1),prach2,(98304<<2));
- // here we have |empty | Prach98304 | Prach98304|
- memmove(prach,prach+(98304<<2),(Ncp<<2));
- // here we have |Prefix | Prach98304 | Prach98304|
- prach_len = (98304*2)+Ncp;
- }
- else if (prach_fmt == 2) {
- idft(IDFT_98304,prachF,prach2,1);
- dftlen=98304;
- memmove(prach2+(98304<<1),prach2,(98304<<2));
- // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304
- memmove(prach2+(98304<<2),prach2,(98304<<3));
- // here we have |empty | Prach98304 | Prach98304| Prach98304 | Prach98304
- memmove(prach,prach+(98304<<3),(Ncp<<2));
- // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304
- prach_len = (98304*4)+Ncp;
- }
- else if (prach_fmt == 3) { // 4x6144, Ncp 3168
- idft(IDFT_24576,prachF,prach2,1);
- dftlen=24576;
- memmove(prach2+(24576<<1),prach2,(24576<<2));
- // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576
- memmove(prach2+(24576<<2),prach2,(24576<<3));
- // here we have |empty | Prach24576 | Prach24576| Prach24576 | Prach24576
- memmove(prach,prach+(24576<<3),(Ncp<<2));
- // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576
- prach_len = (24576*4)+(Ncp<<1);
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- if (prach_fmt != 0xc0) {
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- prach_len = (4096*2)+Ncp;
- }
- else prach_len = (4096*1)+Ncp;
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) |
-
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x4096
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 |
- memmove(prach2+(4096<<2),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 |
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 |
- prach_len = (4096*4)+Ncp;
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x4096
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
- memmove(prach2+(4096<<2),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
- memmove(prach2+((4096<<1)*3),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 |
- prach_len = (4096*6)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x4096
- idft(IDFT_4096,prachF,prach2,1);
- dftlen=4096;
- // here we have |empty | Prach4096 |
- memmove(prach2+(4096<<1),prach2,(4096<<2));
- // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
- memmove(prach2+(4096<<2),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096
- memmove(prach2+(4096<<3),prach2,(4096<<3));
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096
- memmove(prach2+(4096<<1)*6,prach2,(4096<<2)*6);
- // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
- memmove(prach,prach+(4096<<1),(Ncp<<2));
- // here we have |Prefix | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096|
- prach_len = (4096*12)+Ncp;
- }
- }
- else { // 92.16 Ms/s
+ } else { // three quarter sampling @ 92.16 Ms/s
Ncp = (Ncp*3);
prach2 = prach+(Ncp<<1);
- if (prach_fmt == 0) {
- idft(IDFT_73728,prachF,prach2,1);
- dftlen=73728;
- // here we have |empty | Prach73728|
- memmove(prach,prach+(73728<<1),(Ncp<<4));
- // here we have |Prefix | Prach73728|
- prach_len = (73728*1)+Ncp;
- }
- else if (prach_fmt == 1) {
- idft(IDFT_73728,prachF,prach2,1);
- dftlen=73728;
- memmove(prach2+(73728<<1),prach2,(73728<<2));
- // here we have |empty | Prach73728 | Prach73728|
- memmove(prach,prach+(73728<<2),(Ncp<<4));
- // here we have |Prefix | Prach73728 | Prach73728|
- prach_len = (73728*2)+Ncp;
- }
- if (prach_fmt == 2) {
- idft(IDFT_73728,prachF,prach2,1);
- dftlen=73728;
- memmove(prach2+(73728<<1),prach2,(73728<<2));
- // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
- memmove(prach2+(73728<<2),prach2,(73728<<3));
- // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
- memmove(prach,prach+(73728<<3),(Ncp<<4));
- // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
- prach_len = (73728*4)+Ncp;
- }
- else if (prach_fmt == 3) {
- idft(IDFT_18432,prachF,prach2,1);
- dftlen=18432;
- memmove(prach2+(18432<<1),prach2,(18432<<2));
- // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432
- memmove(prach2+(18432<<2),prach2,(18432<<3));
- // here we have |empty | Prach18432 | Prach18432| Prach18432 | Prach18432
- memmove(prach,prach+(18432<<3),(Ncp<<4));
- // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432
- prach_len = (18432*4)+Ncp;
- }
- else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) {
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- if (prach_fmt != 0xc0) {
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- prach_len = (3072*2)+Ncp;
- }
- else prach_len = (3072*1)+Ncp;
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
- }
- else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x3072
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
- memmove(prach2+(3072<<2),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
- memmove(prach2+((3072<<1)*3),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 |
- prach_len = (3072*6)+Ncp;
- }
- else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x3072
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 |
- memmove(prach2+(3072<<2),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 |
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 |
- prach_len = (3072*4)+Ncp;
- }
- else if (prach_fmt == 0xb4) { // 12x3072
- idft(IDFT_3072,prachF,prach2,1);
- dftlen=3072;
- // here we have |empty | Prach3072 |
- memmove(prach2+(3072<<1),prach2,(3072<<2));
- // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
- memmove(prach2+(3072<<2),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
- memmove(prach2+(3072<<3),prach2,(3072<<3));
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
- memmove(prach2+(3072<<1)*6,prach2,(3072<<2)*6);
- // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
- memmove(prach,prach+(3072<<1),(Ncp<<2));
- // here we have |Prefix | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
- prach_len = (3072*12)+Ncp;
+ if (prach_sequence_length == 0){
+ if (prach_fmt_id == 0) {
+ idft(IDFT_73728,prachF,prach2,1);
+ // here we have |empty | Prach73728|
+ memmove(prach,prach+(73728<<1),(Ncp<<2));
+ // here we have |Prefix | Prach73728|
+ prach_len = (73728*1)+Ncp;
+ } else if (prach_fmt_id == 1) {
+ idft(IDFT_73728,prachF,prach2,1);
+ memmove(prach2+(73728<<1),prach2,(73728<<2));
+ // here we have |empty | Prach73728 | Prach73728|
+ memmove(prach,prach+(73728<<2),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728|
+ prach_len = (73728*2)+Ncp;
+ } if (prach_fmt_id == 2) {
+ idft(IDFT_73728,prachF,prach2,1);
+ memmove(prach2+(73728<<1),prach2,(73728<<2));
+ // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
+ memmove(prach2+(73728<<2),prach2,(73728<<3));
+ // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728
+ memmove(prach,prach+(73728<<3),(Ncp<<2));
+ // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
+ prach_len = (73728*4)+Ncp;
+ } else if (prach_fmt_id == 3) {
+ idft(IDFT_18432,prachF,prach2,1);
+ memmove(prach2+(18432<<1),prach2,(18432<<2));
+ // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432
+ memmove(prach2+(18432<<2),prach2,(18432<<3));
+ // here we have |empty | Prach18432 | Prach18432| Prach18432 | Prach18432
+ memmove(prach,prach+(18432<<3),(Ncp<<2));
+ // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432
+ prach_len = (18432*4)+Ncp;
+ }
+ } else { // short sequence
+ if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ if (prach_fmt_id != 7) {
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ prach_len = (3072*2)+Ncp;
+ } else prach_len = (3072*1)+Ncp;
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
+ } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x3072
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<2),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<3),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 |
+ prach_len = (3072*6)+Ncp;
+ } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x3072
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 |
+ memmove(prach2+(3072<<2),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 |
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 |
+ prach_len = (3072*4)+Ncp;
+ } else if (prach_fmt_id == 6) { // 12x3072
+ Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
+ prach2 = prach+(Ncp<<1);
+ idft(IDFT_3072,prachF,prach2,1);
+ // here we have |empty | Prach3072 |
+ memmove(prach2+(3072<<1),prach2,(3072<<2));
+ // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<2),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072
+ memmove(prach2+(3072<<3),prach2,(3072<<3));
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072
+ memmove(prach2+(3072<<1)*6,prach2,(3072<<2)*6);
+ // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
+ memmove(prach,prach+(3072<<1),(Ncp<<2));
+ // here we have |Prefix | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072|
+ prach_len = (3072*12)+Ncp;
+ }
}
}
- }
-
-
-
-
-#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
- int j;
- int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe;
- LOG_D( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow );
-
- for (i=prach_start,j=0; isamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) {
- ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
- ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
}
- for (i=0; icommon_vars.txdata[0])[2*i] = prach[2*j];
- ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
- }
-#else
+ #ifdef NR_PRACH_DEBUG
+ LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", Mod_id,
+ fp->N_RB_UL,
+ prach_start,
+ prach_len,
+ ue->rx_offset,
+ ue->hw_timing_advance,
+ ue->N_TA_offset);
+ #endif
- LOG_D( PHY, "prach_start=%d\n", prach_start);
+ #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+ int j, overflow = prach_start + prach_len - NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe;
- for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
- ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
- }
-#endif
+ #ifdef NR_PRACH_DEBUG
+ LOG_I( PHY, "PRACH [UE %d] overflow = %d\n", Mod_id, overflow);
+ #endif
+ // prach_start=414.730, overflow=-39470 prach_len=6600 fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME 460.800 prach_start+prach_len 421.330 fp->samples_per_subframe 46080
+ // from prach_start=414.730 to prach_start+prach_len 421.330
+ for (i = prach_start, j = 0; i < min(fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME, prach_start + prach_len); i++, j++) {
+ ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
+ ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
+ }
-#if defined(PRACH_WRITE_OUTPUT_DEBUG)
- LOG_M("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1);
- LOG_M("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1);
- LOG_M("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]),fp->samples_per_subframe,1,1);
- exit(-1);
-#endif
+ for (i = 0; i < overflow; i++,j++) {
+ ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
+ ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
+ }
+ #else // simulators
+ for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
+ ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
+ }
+ #endif
- return signal_energy( (int*)prach, 256 );
+ //printf("----------------------\n");
+ //for(int ii = prach_start; ii<2*(prach_start + prach_len); ii++){
+ // printf("PRACH rx data[%d] = %d\n", ii, ue->common_vars.txdata[0][ii]);
+ //}
+ //printf(" \n");
+
+ #if defined(PRACH_WRITE_OUTPUT_DEBUG)
+ LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1);
+ LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1)
+ #endif
+
+ return signal_energy((int*)prach, 256);
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 4aae9ef7b4..d84a56eee5 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -37,6 +37,9 @@
#include
#include "nfapi_interface.h"
+#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
+#define NR_PUSCH_y 3 // UCI placeholder bit
+
// Functions below implement 36-211 and 36-212
/** @addtogroup _PHY_TRANSPORT_
@@ -66,24 +69,6 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulsch,unsigned char N_RB_UL);
NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
-void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
-
-int rx_pmch(PHY_VARS_NR_UE *phy_vars_ue,
- unsigned char eNB_id,
- uint8_t subframe,
- unsigned char symbol);
-
-/** \brief Dump OCTAVE/MATLAB files for PMCH debugging
- @param phy_vars_ue Pointer to UE variables
- @param eNB_id index of eNB in ue variables
- @param coded_bits_per_codeword G from 36.211
- @param subframe Index of subframe
- @returns 0 on success
-*/
-void dump_mch(PHY_VARS_NR_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe);
-
-
-
/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
@param stream0_in Input from channel compensated (MR combined) stream 0
@param stream1_in Input from channel compensated (MR combined) stream 1
@@ -1540,11 +1525,11 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME
void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi);
-void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot,
- int16_t *z, int16_t *z2,uint32_t length, uint16_t pdcch_DMRS_scrambling_id);
-
-
-
+void nr_pdcch_unscrambling(int16_t *z,
+ uint16_t scrambling_RNTI,
+ uint32_t length,
+ uint16_t pdcch_DMRS_scrambling_id,
+ int16_t *z2);
void dlsch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
int mbsfn_flag,
@@ -1757,9 +1742,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
-
-
-int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf );
+int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe);
void *dlsch_thread(void *arg);
/**@}*/
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index bb92508934..b4b33ca501 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -42,9 +42,7 @@
#include "UTIL/LISTS/list.h"
#endif
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h"
-//#include "../LTE_TRANSPORT/transport_common.h"
// structures below implement 36-211 and 36-212
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index 556a5626c5..a9f2305b05 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -283,6 +283,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
printf("%02x.",a[i]);
printf("\n");
*/
+
if (A > 3824) {
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(harq_process->a,A)>>8;
@@ -312,7 +313,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
memcpy(harq_process->b,harq_process->a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc
}
-
///////////
///////////////////////////////////////////////////////////////////////////
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index da0528655f..9be4a16fb5 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -114,6 +114,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t data_existing =0;
uint8_t L_ptrs, K_ptrs; // PTRS parameters
uint16_t beta_ptrs; // PTRS parameter related to power control
+ uint8_t no_data_in_dmrs = 1;
NR_UE_ULSCH_t *ulsch_ue;
NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL;
@@ -127,6 +128,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
number_dmrs_symbols = 0;
+
for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) {
ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
@@ -146,7 +148,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
rnti = harq_process_ul_ue->pusch_pdu.rnti;
ulsch_ue->Nid_cell = Nid_cell;
- nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4);
+
+ if(no_data_in_dmrs)
+ nb_dmrs_re_per_rb = 12;
+ else
+ nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4);
N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
@@ -165,8 +171,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
number_of_symbols,
nb_dmrs_re_per_rb*number_dmrs_symbols,
0,
+ 0,
harq_process_ul_ue->pusch_pdu.nrOfLayers);
+
uint8_t access_mode = SCHEDULED_ACCESS;
//-----------------------------------------------------//
@@ -176,38 +184,38 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
TBS = harq_process_ul_ue->pusch_pdu.pusch_data.tb_size;
data_existing = 0;
- if (IS_SOFTMODEM_NOS1){
+ if (IS_SOFTMODEM_NOS1){
data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame,
- slot, 0, ulsch_input_buffer, TBS/8, &access_mode);
- //IP traffic to be transmitted
+ slot, 0, ulsch_input_buffer, TBS/8, &access_mode);
+ //IP traffic to be transmitted
if(data_existing){
//harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char));
memcpy(harq_process_ul_ue->a, ulsch_input_buffer, TBS/8);
-
- #ifdef DEBUG_MAC_PDU
- LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8);
- for (i = 0; i < TBS / 8; i++) {
- printf("0x%02x",harq_process_ul_ue->a[i]);
- }
- printf("\n");
- #endif
- }
+ }
}
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
//and block this traffic from being forwarded to the upper layers at the gNB
- uint16_t payload_offset = 5;
LOG_D(PHY, "Random data to be tranmsitted: \n");
- //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver
- for (i = 0; ia[i] = 0;
- for (i = payload_offset; i < TBS / 8; i++) {
+ //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
+ //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
+ //have a valid LCID (nr_process_mac_pdu function)
+ harq_process_ul_ue->a[0] = 0x31;
+
+ for (i = 1; i < TBS / 8; i++) {
harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
}
+#ifdef DEBUG_MAC_PDU
+ LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8);
+ for (i = 0; i < TBS / 8; i++) {
+ printf("%02x",harq_process_ul_ue->a[i]);
+ }
+ printf("\n");
+#endif
} else {
LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
return;
@@ -220,7 +228,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned int G = nr_get_G(nb_rb, number_of_symbols,
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
-
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
///////////
@@ -264,7 +271,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////DMRS Modulation/////////////////////////
///////////
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
- n_dmrs = (nb_rb*nb_dmrs_re_per_rb*number_dmrs_symbols);
+ n_dmrs = (nb_rb*((dmrs_type == pusch_dmrs_type1) ? 6:4)*number_dmrs_symbols);
int16_t mod_dmrs[n_dmrs<<1];
///////////
////////////////////////////////////////////////////////////////////////
@@ -301,9 +308,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
tx_layers = (int16_t **)pusch_ue->txdataF_layers;
nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id],
- Nl,
- available_bits/mod_order,
- tx_layers);
+ Nl,
+ available_bits/mod_order,
+ tx_layers);
///////////
////////////////////////////////////////////////////////////////////////
@@ -432,18 +439,24 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
ptrs_idx++;
- } else {
+ } else if (((ul_dmrs_symb_pos >> l) & 0x01) == 0) {
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1];
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1];
- #ifdef DEBUG_PUSCH_MAPPING
- printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
- m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
- ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
- #endif
+ #ifdef DEBUG_PUSCH_MAPPING
+ printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
+ m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
+ ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
+ #endif
m++;
+
+ } else {
+
+ ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = 0;
+ ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = 0;
+
}
if (++k >= frame_parms->ofdm_symbol_size)
@@ -453,6 +466,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
}
//}
+ NR_UL_UE_HARQ_t *harq_process_ulsch=NULL;
+ harq_process_ulsch = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid];
+ harq_process_ulsch->status = SCH_IDLE;
///////////
////////////////////////////////////////////////////////////////////////
@@ -498,21 +514,51 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
txdata = UE->common_vars.txdata;
txdataF = UE->common_vars.txdataF;
- for (ap = 0; ap < Nl; ap++) {
+ if(UE->N_TA_offset > tx_offset) {
+ int32_t *tmp_idft_out = (int32_t*)malloc16(frame_parms->get_samples_per_slot(slot, frame_parms) * sizeof(int32_t));
+
+ for(ap = 0; ap < Nl; ap++) {
if (frame_parms->Ncp == 1) { // extended cyclic prefix
- PHY_ofdm_mod(txdataF[ap],
- &txdata[ap][tx_offset],
- frame_parms->ofdm_symbol_size,
- 12,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
+ PHY_ofdm_mod(txdataF[ap],
+ tmp_idft_out,
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
} else { // normal cyclic prefix
- nr_normal_prefix_mod(txdataF[ap],
- &txdata[ap][tx_offset],
- 14,
- frame_parms);
+ nr_normal_prefix_mod(txdataF[ap],
+ tmp_idft_out,
+ 14,
+ frame_parms);
+ }
+
+ memcpy((void *) &txdata[ap][frame_parms->samples_per_frame - UE->N_TA_offset + tx_offset],
+ (void *) tmp_idft_out,
+ (UE->N_TA_offset - tx_offset) * sizeof(int32_t));
+
+ memcpy((void *) &txdata[ap][0],
+ (void *) &tmp_idft_out[UE->N_TA_offset - tx_offset],
+ (frame_parms->get_samples_per_slot(slot, frame_parms) - UE->N_TA_offset + tx_offset) * sizeof(int32_t));
+ }
+
+ free(tmp_idft_out);
+ } else { // UE->N_TA_offset <= tx_offset
+ for (ap = 0; ap < Nl; ap++) {
+ if (frame_parms->Ncp == 1) { // extended cyclic prefix
+ PHY_ofdm_mod(txdataF[ap],
+ &txdata[ap][tx_offset-UE->N_TA_offset],
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ } else { // normal cyclic prefix
+ nr_normal_prefix_mod(txdataF[ap],
+ &txdata[ap][tx_offset-UE->N_TA_offset],
+ 14,
+ frame_parms);
}
}
+ }
///////////
////////////////////////////////////////////////////
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
index c8f7268d04..e1358602ce 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
@@ -799,27 +799,47 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
}
#endif //0
-inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) __attribute__((always_inline));
-inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) {
+inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) __attribute__((always_inline));
+inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) {
uint32_t x1, x2, s=0;
int i;
uint8_t c;
// c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1
//x2 = (rnti) + ((uint32_t)(1+nr_tti_tx)<<16)*(1+(fp->Nid_cell<<1));
x2 = ((rnti)<<15)+n_id;
- s = lte_gold_generic(&x1, &x2, 1);
#ifdef DEBUG_NR_PUCCH_TX
- printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x\n",s);
+ printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit);
#endif
- for (i=0; i>i)&1);
- btilde[i] = (((B>>i)&1) ^ c);
+ uint8_t *btildep=btilde;
+ int M_bit2=M_bit > 31 ? 32 : (M_bit&31), M_bit3=M_bit;
+ uint32_t B;
+ for (int iprime=0;iprime<=(M_bit>>5);iprime++,btildep+=32) {
+ s = lte_gold_generic(&x1, &x2, (iprime==0) ? 1 : 0);
+ B=((uint32_t*)B64)[iprime];
+ for (int n=0;n>n)&1,
+ (B>>(n+1))&1,
+ (B>>(n+2))&1,
+ (B>>(n+3))&1,
+ (B>>(n+4))&1,
+ (B>>(n+5))&1,
+ (B>>(n+6))&1,
+ (B>>(n+7))&1
+ );
+ for (i=0; i>i)&1);
+ btildep[i] = (((B>>i)&1) ^ c);
#ifdef DEBUG_NR_PUCCH_TX
- //printf("\t\t\t btilde[%d]=%lx from scrambled bit %d\n",i,btilde[i],((B>>i)&1));
+ printf("\t\t\t btilde[%d]=%lx from unscrambled bit %d and scrambling %d (%x)\n",i+(iprime<<5),btilde[i],((B>>i)&1),c,s>>i);
#endif
+ }
+ M_bit3-=32;
+ M_bit2=M_bit3 > 31 ? 32 : (M_bit3&31);
}
+
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
#endif
@@ -909,24 +929,13 @@ void nr_uci_encoding(uint64_t payload,
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
b[0] = encodeSmallBlock((uint16_t*)&payload,A);
} else if (A>=12) {
- AssertFatal(1==0,"Polar encoding not supported yet for UCI\n");
- // procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1)
- /*if ((A>=360 && E>=1088)||(A>=1013)) {
- I_seg = 1;
- } else {
- I_seg = 0;
- }*/
-
- /*if (A>=20) {
- // parity bits (subclause 5.2.1) computed by setting L=11 and using generator polynomial gCRC11(D) (subclause 5.1)
- L=11;
- } else if (A<=19) {
- // parity bits (subclause 5.2.1) computed by setting L=6 and using generator polynomial gCRC6(D) (subclause 5.1)
- L=6;
- }*/
-
- // code block segmentation and CRC attachment is performed according to subclause 5.2.1
- // polar coding subclause 5.3.1
+ AssertFatal(A<65,"Polar encoding not supported yet for UCI with more than 64 bits\n");
+ t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_UCI_PUCCH_MESSAGE_TYPE,
+ A,
+ nrofPRB,
+ 1,
+ NULL);
+ polar_encoder_fast(&payload, b, 0,0,currentPtr);
}
}
@@ -950,7 +959,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
printf("\t [nr_generate_pucch2] start function at slot(nr_tti_tx)=%d with payload=%lu and nr_bit=%d\n",nr_tti_tx, payload, nr_bit);
#endif
// b is the block of bits transmitted on the physical channel after payload coding
- uint64_t b;
+ uint64_t b[16]; // limit to 1024-bit encoded length
// M_bit is the number of bits of block b (payload after encoding)
uint16_t M_bit;
nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b,&M_bit);
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 8c92214e68..45eb66b4e3 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -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.
@@ -26,6 +28,7 @@
#include "executables/nr-softmodem-common.h"
#define TPUT_WINDOW_LENGTH 100
+#define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe));
int otg_enabled;
FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
@@ -36,10 +39,40 @@ float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
+typedef struct {
+ int16_t r;
+ int16_t i;
+} scopeSample_t;
+#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
-static void ia_receiver_on_off( FL_OBJECT *button, long arg)
-{
+typedef struct OAIgraph {
+ FL_OBJECT *graph;
+ void (*gNBfunct) (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id);
+ void (*nrUEfunct) (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
+} OAIgraph_t;
+/* Forms and Objects */
+typedef struct {
+ FL_FORM *phy_scope;
+ OAIgraph_t graph[20];
+ FL_OBJECT *button_0;
+} FD_phy_scope_t;
+
+typedef struct {
+ FL_FORM *stats_form;
+ void *vdata;
+ char *cdata;
+ long ldata;
+ FL_OBJECT *stats_text;
+ FL_OBJECT *stats_button;
+} FD_stats_form;
+
+static void drawsymbol(FL_OBJECT *obj, int id,
+ FL_POINT *p, int n, int w, int h) {
+ fl_points( p, n, FL_YELLOW);
+}
+
+static void ia_receiver_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "IA Receiver ON");
// PHY_vars_UE_g[0][0]->use_ia_receiver = 1;
@@ -51,9 +84,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg)
}
}
-static void dl_traffic_on_off( FL_OBJECT *button, long arg)
-{
-
+static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "DL Traffic ON");
otg_enabled = 1;
@@ -65,764 +96,643 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg)
}
}
-FD_phy_scope_gnb *create_phy_scope_gnb( void )
-{
-
- FL_OBJECT *obj;
- FD_phy_scope_gnb *fdui = fl_malloc( sizeof *fdui );
-
- // Define form
- fdui->phy_scope_gnb = fl_bgn_form( FL_NO_BOX, 800, 800 );
-
- // This the whole UI box
- obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
- fl_set_object_color( obj, FL_BLACK, FL_BLACK );
-
- // Received signal
- fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
- fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
-
- // Time-domain channel response
- fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "SRS Frequency Response (samples, abs)" );
- fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
-
- // Frequency-domain channel response
- fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
- fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds( fdui->chest_f,30,70);
-
- // LLR of PUSCH
- fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pusch_llr,2);
-
- // I/Q PUSCH comp
- fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pusch_comp, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pusch_comp,2);
- fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
-
- // I/Q PUCCH comp (format 1)
- fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" );
- fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pucch_comp1, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pucch_comp1,2);
- // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
-
- // I/Q PUCCH comp (fromat 1a/b)
- fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pucch_comp, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pucch_comp,2);
- // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
-
- // Throughput on PUSCH
- fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" );
- fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE );
- fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color
-
- // Generic eNB Button
- fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
- fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
- fl_set_button(fdui->button_0,0);
- otg_enabled = 0;
- fl_set_object_label(fdui->button_0, "DL Traffic OFF");
- fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
- fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
-
- fl_end_form( );
- fdui->phy_scope_gnb->fdui = fdui;
-
- return fdui;
+static FL_OBJECT *commonGraph( int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+ FL_OBJECT *graph;
+ graph=fl_add_xyplot(type, x, y, w, h, label);
+ fl_set_object_boxtype(graph, FL_EMBOSSED_BOX );
+ fl_set_object_lcolor(graph, FL_WHITE ); // Label color
+ fl_set_xyplot_symbol(graph, 0, drawsymbol);
+ fl_set_object_color(graph, FL_BLACK, pointColor);
+ return graph;
}
-void phy_scope_gNB(FD_phy_scope_gnb *form,
+static OAIgraph_t gNBcommonGraph( void (*funct) (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id),
+ int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+ OAIgraph_t graph;
+ graph.graph=commonGraph(type, x, y, w, h, label, pointColor);
+ graph.gNBfunct=funct;
+ graph.nrUEfunct=NULL;
+ return graph;
+}
+
+static OAIgraph_t nrUEcommonGraph( void (*funct) (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id),
+ int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+ OAIgraph_t graph;
+ graph.graph=commonGraph(type, x, y, w, h, label, pointColor);
+ graph.gNBfunct=NULL;
+ graph.nrUEfunct=funct;
+ return graph;
+}
+
+void phy_scope_gNB(FD_phy_scope_t *form,
PHY_VARS_gNB *phy_vars_gnb,
- RU_t *phy_vars_ru,
- int UE_id)
-{
- int i, arx; //int i,i2,arx,atx,ind,k;
- NR_DL_FRAME_PARMS *frame_parms = &phy_vars_gnb->frame_parms;
- //int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti;
- uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
- //uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE
- int16_t **rxsig_t, **rxsig_f;
- // int16_t **chest_t=NULL;
- // int16_t **chest_f=NULL;
- // int16_t *pusch_llr=NULL;
- // int32_t *pusch_comp=NULL;
- // int32_t *pucch1_comp=NULL;
- // int32_t *pucch1_thres=NULL;
- // int32_t *pucch1ab_comp=NULL;
- // float Re,Im,ymax;
- float *llr, *bit;
- // float I[nsymb_ce*2], Q[nsymb_ce*2];
- // float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240];
- float *rxsig_t_dB[nb_antennas_rx];
- float *rxsig_f_dB[nb_antennas_rx];
- float time[frame_parms->samples_per_frame];
- // float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
- // uint32_t total_dlsch_bitrate = phy_vars_gnb->total_dlsch_bitrate;
- int coded_bits_per_codeword = 0;
- // uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
- int Qm = 2;
+ RU_t *phy_vars_ru,
+ int UE_id) {
+ static FD_phy_scope_t *remeberForm=NULL;
- /*
- if (!RC.nrmac[0]->UE_info.active[UE_id])
- return;
-
- // choose max MCS to compute coded_bits_per_codeword
- if (phy_vars_gnb->ulsch[UE_id][0]!=NULL) {
- for (harq_pid=0; harq_pid<3; harq_pid++) {
- //Qm = cmax(phy_vars_gnb->ulsch[UE_id][0]->harq_processes->Qm,Qm);
- }
+ if (form==NULL)
+ form=remeberForm;
+ else
+ remeberForm=form;
+
+ if (form==NULL) return;
+
+ int i=0;
+
+ while (form->graph[i].graph) {
+ form->graph[i].gNBfunct(form->graph[i].graph, phy_vars_gnb, phy_vars_ru, UE_id);
+ i++;
}
- */
- coded_bits_per_codeword = frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
- for (arx=0; arxsamples_per_frame,sizeof(float));
- rxsig_f_dB[arx] = (float*) calloc(frame_parms->samples_per_slot_wCP,sizeof(float));
- }
- llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
- bit = malloc(coded_bits_per_codeword*sizeof(float));
-
- rxsig_t = (int16_t**) phy_vars_ru->common.rxdata;
- rxsig_f = (int16_t**) phy_vars_ru->common.rxdataF;
- //chest_t = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id];
- /* chest_t = (int16_t**) phy_vars_gnb->srs_vars[UE_id].srs_ch_estimates;
- chest_f = (int16_t**) phy_vars_gnb->pusch_vars[UE_id]->drs_ch_estimates;
- pusch_llr = (int16_t*) phy_vars_gnb->pusch_vars[UE_id]->llr;
- pusch_comp = (int32_t*) phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp;
- pucch1_comp = (int32_t*) phy_vars_gnb->pucch1_stats[UE_id];
- pucch1_thres = (int32_t*) phy_vars_gnb->pucch1_stats_thres[UE_id];
- pucch1ab_comp = (int32_t*) phy_vars_gnb->pucch1ab_stats[UE_id];
- */
+ fl_check_forms();
+}
+static void timeSignal (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
// Received signal in time domain of receive antenna 0
- if (rxsig_t != NULL) {
- if (rxsig_t[0] != NULL) {
- for (i=0; isamples_per_frame; i++) {
- rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
- time[i] = (float) i;
+ if (!phy_vars_ru->common.rxdata)
+ return;
+
+ NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ scopeSample_t **rxsig_t = (scopeSample_t **)phy_vars_ru->common.rxdata;
+ float rxsig_t_dB[frame_parms->samples_per_frame];
+ float time[frame_parms->samples_per_frame];
+
+ for (int arx=0; arxsamples_per_frame; i++) {
+ rxsig_t_dB[i] = 10*log10(1.0+SquaredNorm(rxsig_t[arx][i]));
+ time[i] = i;
}
- fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],frame_parms->samples_per_frame,"","","");
+ if (arx==0)
+ fl_set_xyplot_data(graph,time,rxsig_t_dB, frame_parms->samples_per_frame,"","","");
+ else
+ fl_add_xyplot_overlay(graph,arx,time,rxsig_t_dB,frame_parms->samples_per_frame,rx_antenna_colors[arx]);
}
+ }
+}
- for (arx=1; arxsamples_per_frame; i++) {
- rxsig_t_dB[arx][i] = 10*log10(1.0+(float) ((rxsig_t[arx][2*i])*(rxsig_t[arx][2*i])+(rxsig_t[arx][2*i+1])*(rxsig_t[arx][2*i+1])));
- }
+static void timeResponse (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
+ if (!phy_vars_gnb->pusch_vars[UE_id]->ul_ch_estimates_time)
+ return;
- fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],frame_parms->samples_per_frame,rx_antenna_colors[arx]);
+ NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ scopeSample_t **chest_t = (scopeSample_t **) phy_vars_gnb->pusch_vars[UE_id]->ul_ch_estimates_time;
+ int ymax = 0;
+ float time2[2*frame_parms->ofdm_symbol_size];
+ float chest_t_abs[2*frame_parms->ofdm_symbol_size];
+
+ for (int arx=0; arxofdm_symbol_size); i++) {
+ time2[i] = (float)i;
+ chest_t_abs[i] = 10*log10(1.0 + SquaredNorm(chest_t[0][i]));
+
+ if (chest_t_abs[i] > ymax)
+ ymax = chest_t_abs[i];
+ }
+
+ if (arx==0)
+ fl_set_xyplot_data(graph,time2,chest_t_abs,(2*frame_parms->ofdm_symbol_size),"","","");
+ else {
+ fl_add_xyplot_overlay(graph,arx,time2,chest_t_abs,(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
+ fl_set_xyplot_overlay_type(graph,arx,FL_DASHED_XYPLOT);
}
}
}
+ // Avoid flickering effect
+ // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
+ fl_set_xyplot_ybounds(graph,0,ymax);
+}
+
+static void frequencyResponse (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
+ // Channel Frequency Response
+ if (!phy_vars_ru->common.rxdataF)
+ return;
+
+ NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+ //uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ scopeSample_t **rxsig_f = (scopeSample_t **) phy_vars_ru->common.rxdataF;
+ float rxsig_f_dB[frame_parms->samples_per_slot_wCP];
+ float time[frame_parms->samples_per_slot_wCP];
+
+ if (rxsig_f[0] != NULL) {
+ for (int i=0; isamples_per_slot_wCP; i++) {
+ rxsig_f_dB[i] = 10*log10(1.0+ SquaredNorm(rxsig_f[0][i]));
+ time[i] = (float) i;
+ }
+
+ fl_set_xyplot_data(graph,time,rxsig_f_dB,frame_parms->samples_per_slot_wCP,"","","");
+ }
+
/*
- // Channel Impulse Response
- if (chest_t != NULL) {
- ymax = 0;
-
- if (chest_t[0] !=NULL) {
- for (i=0; i<(frame_parms->ofdm_symbol_size); i++) {
- //i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
- i2=i;
- //time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
- time2[i] = (float)i;
- chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1]));
-
- if (chest_t_abs[0][i] > ymax)
- ymax = chest_t_abs[0][i];
+ for (int arx=1; arxchest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","","");
+ fl_add_xyplot_overlay(form->chest_f,1,time,chest_f_abs,nsymb_ce,rx_antenna_colors[arx]);
}
-
- for (arx=1; arxofdm_symbol_size>>3); i++) {
- chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
-
- if (chest_t_abs[arx][i] > ymax)
- ymax = chest_t_abs[arx][i];
- }
-
- fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
- fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
- }
- }
-
- // Avoid flickering effect
- // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
- fl_set_xyplot_ybounds(form->chest_t,0,ymax);
}
*/
-
- // Channel Frequency Response
- if (rxsig_f != NULL) {
- if (rxsig_f[0] != NULL) {
- for (i=0; isamples_per_slot_wCP; i++) {
- rxsig_f_dB[0][i] = 10*log10(1.0+(float) ((rxsig_f[0][2*i])*(rxsig_f[0][2*i])+(rxsig_f[0][2*i+1])*(rxsig_f[0][2*i+1])));
- time[i] = (float) i;
- }
-
- fl_set_xyplot_data(form->chest_t,time,rxsig_f_dB[0],frame_parms->samples_per_slot_wCP,"","","");
- }
- }
-
/*
-
- for (arx=0; arxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3);
fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+ */
+}
- for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
-
- // other tx antennas
- if (nb_antennas_tx > 1) {
- if (nb_antennas_rx > 1) {
- for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- } else { // 1 rx antenna
- atx=1;
- arx=0;
- fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- }
-
+static void puschLLR (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
// PUSCH LLRs
- if (pusch_llr != NULL) {
- for (i=0; ipusch_vars[UE_id]->llr)
+ return;
- fl_set_xyplot_data(form->pusch_llr,bit,llr,coded_bits_per_codeword,"","","");
+ //NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+ //int Qm = 2;
+ int16_t *pusch_llr = (int16_t *) phy_vars_gnb->pusch_vars[UE_id]->llr;
+ int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
+ float llr[coded_bits_per_codeword];
+ float bit[coded_bits_per_codeword];
+
+ for (int i=0; ipusch_vars[UE_id]->rxdataF_comp)
+ return;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_UL; i++) {
- I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
- Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1];
- ind++;
- }
- }
+ NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+ scopeSample_t *pusch_comp = (scopeSample_t *) phy_vars_gnb->pusch_vars[UE_id]->rxdataF_comp[0];
+ int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
+ float I[sz], Q[sz];
- fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
+ for (int k=0; kpucch1ab_stats[UE_id];
+ int32_t *pucch1_comp = (int32_t *) NULL; //phy_vars_gnb->pucch1_stats[UE_id];
+ float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240];
+
+ for (int ind=0; ind<10240; ind++) {
I_pucch[ind] = (float)pucch1ab_comp[2*(ind)];
Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1];
A_pucch[ind] = pucch1_comp?(10*log10(pucch1_comp[ind])):0;
B_pucch[ind] = ind;
+ int32_t *pucch1_thres = (int32_t *) NULL; // phy_vars_gnb->pucch1_stats_thres[UE_id];
C_pucch[ind] = pucch1_thres?(float)pucch1_thres[ind]:0;
}
- fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
- fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
- fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED);
- fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000);
- fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000);
- fl_set_xyplot_ybounds(form->pucch_comp1,0,80);
+ fl_set_xyplot_data(graph,I_pucch,Q_pucch,10240,"","","");
+ fl_set_xyplot_data(graph,B_pucch,A_pucch,1024,"","","");
+ fl_add_xyplot_overlay(graph,1,B_pucch,C_pucch,1024,FL_RED);
+ fl_set_xyplot_ybounds(graph,-5000,5000);
+ fl_set_xyplot_xbounds(graph,-5000,5000);
+ fl_set_xyplot_ybounds(graph,0,80);
}
+#endif
+}
+static void pucchEnergy (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
+}
+static void pucchIQ (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
+}
+
+static void puschThroughtput (FL_OBJECT *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) {
// PUSCH Throughput
memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
-
tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) 0;
-// tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
-
- fl_set_xyplot_data(form->pusch_tput,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","","");
-
+ // tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
+ fl_set_xyplot_data(graph,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","","");
// fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax);
// fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
-
- */
-
- fl_check_forms();
-
- free(llr);
- free(bit);
}
-FD_phy_scope_nrue *create_phy_scope_nrue( void )
-{
-
+static FD_phy_scope_t *create_phy_scope_gnb(int UE_id ) {
FL_OBJECT *obj;
- FD_phy_scope_nrue *fdui = fl_malloc( sizeof *fdui );
-
+ FD_phy_scope_t *fdui = fl_malloc( sizeof *fdui );
// Define form
- fdui->phy_scope_nrue = fl_bgn_form( FL_NO_BOX, 800, 900 );
-
+ fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 );
// This the whole UI box
- obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" );
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
-
// Received signal
- fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
- fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
-
+ fdui->graph[0] = gNBcommonGraph( timeSignal, FL_IMPULSE_XYPLOT, 20, 20, 370, 100,
+ "Received Signal (Time-Domain, dB)", FL_RED );
// Time-domain channel response
- fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
- fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
-
+ fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, 20, 370, 100,
+ "SRS Frequency Response (samples, abs)", FL_RED );
// Frequency-domain channel response
- fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
- fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds( fdui->chest_f,30,70);
+ fdui->graph[2] = gNBcommonGraph( frequencyResponse, FL_IMPULSE_XYPLOT, 20, 140, 760, 100,
+ "Channel Frequency Response (RE, dB)", FL_RED );
+ // LLR of PUSCH
+ fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 20, 260, 500, 200,
+ "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
+ // I/Q PUSCH comp
+ fdui->graph[4] = gNBcommonGraph( puschIQ, FL_POINTS_XYPLOT, 540, 260, 240, 200,
+ "PUSCH I/Q of MF Output", FL_YELLOW );
+ // I/Q PUCCH comp (format 1)
+ fdui->graph[5] = gNBcommonGraph( pucchEnergy, FL_POINTS_XYPLOT, 540, 480, 240, 100,
+ "PUCCH1 Energy (SR)", FL_YELLOW );
+ // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
+ // I/Q PUCCH comp (fromat 1a/b)
+ fdui->graph[6] = gNBcommonGraph( pucchIQ, FL_POINTS_XYPLOT, 540, 600, 240, 100,
+ "PUCCH I/Q of MF Output", FL_YELLOW );
+ // Throughput on PUSCH
+ fdui->graph[7] = gNBcommonGraph( puschThroughtput, FL_NORMAL_XYPLOT, 20, 480, 500, 100,
+ "PUSCH Throughput [frame]/[kbit/s]", FL_WHITE );
+ fdui->graph[8].graph=NULL;
- // LLR of PBCH
- fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
- fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
- fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
- //fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
-
- // I/Q PBCH comp
- fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
- fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
- // fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
- // fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
-
- // LLR of PDCCH
- fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
- fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
-
- // I/Q PDCCH comp
- fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
- fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
- fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
-
- // LLR of PDSCH
- fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
- fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
-
- // I/Q PDSCH comp
- fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
-
- // Throughput on PDSCH
- fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
- fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
- fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
-
- // Generic UE Button
- fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
- fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
- //openair_daq_vars.use_ia_receiver = 0;
- fl_set_button(fdui->button_0,0);
- fl_set_object_label(fdui->button_0, "IA Receiver OFF");
- fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
- fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
- fl_hide_object(fdui->button_0);
+ // Generic eNB Button
+ if (0) { // code kept to later add command buttons
+ fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
+ fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
+ fl_set_button(fdui->button_0,0);
+ otg_enabled = 0;
+ fl_set_object_label(fdui->button_0, "DL Traffic OFF");
+ fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
+ fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
+ }
fl_end_form( );
- fdui->phy_scope_nrue->fdui = fdui;
-
+ fdui->phy_scope->fdui = fdui;
+ char title[100];
+ sprintf (title, "LTE UL SCOPE eNB for UE %d",UE_id);
+ fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
return fdui;
}
-void phy_scope_nrUE(FD_phy_scope_nrue *form,
- PHY_VARS_NR_UE *phy_vars_ue,
- int eNB_id,
- int UE_id,
- uint8_t subframe)
-{
- int i,arx,atx,ind,k;
- NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
- //int nsymb_ce = frame_parms->ofdm_symbol_size;//*frame_parms->symbols_per_tti;
- int samples_per_frame = frame_parms->samples_per_frame;
- uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
- uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB;
- int16_t **rxsig_t;
- float **rxsig_t_dB;
- float *time;
- float *corr;
- int16_t **chest_t;
- int16_t **chest_f;
- int16_t *pdsch_llr;
- int16_t *pdsch_comp;
- //int16_t *pdsch_mag;
- int8_t *pdcch_llr;
- int16_t *pdcch_comp;
- int16_t *pbch_llr;
- int16_t *pbch_comp;
- float llr_pbch[1920], bit_pbch[1920];
- float *llr, *bit;
- float *llr_pdcch, *bit_pdcch;
- float *I, *Q;
- int num_pdcch_symbols=2;
- int num_re = 4500;
- int Qm = 2;
- int coded_bits_per_codeword = num_re*Qm;
- int symbol, first_symbol=2,nb_re;
- int nb_rb_pdsch=50,nb_symb_sch=9;
- float ymax=1;
- float **chest_t_abs;
- float Re,Im;
- float *chest_f_abs;
- float *freq;
- static int overlay = 0;
- /*
- int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
- int mcs = 0;
- unsigned char harq_pid = 0;
- */
+static FD_phy_scope_t *form_gnb[NUMBER_OF_UE_MAX]= {0};
+static unsigned char scope_enb_num_ue = 1;
- /*
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
- harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
+static void *scope_thread_gNB(void *arg) {
+ scopeParms_t *p=(scopeParms_t *) arg;
+ //# ifdef ENABLE_XFORMS_WRITE_STATS
+ // FILE *gNB_stats = fopen("gNB_stats.txt", "w");
+ //#endif
+ size_t stksize;
+ pthread_attr_t atr;
+ pthread_attr_getstacksize(&atr, &stksize);
+ pthread_attr_setstacksize(&atr,32*1024*1024 );
+ sleep(3); // no clean interthread barriers
- if (harq_pid>=8)
- return;
+ while (!oai_exit) {
+ int ue_cnt=0;
- mcs = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
-
- // Button 0
- if(!phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
- // we are in TM5
- fl_show_object(form->button_0);
+ for(int UE_id=0; UE_idgNB, p->ru, UE_id);
+ ue_cnt++;
+ }
}
+
+ usleep(99*1000);
}
- if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
- num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
- }
+ // printf("%s",stats_buffer);
+ /*#ifdef ENABLE_XFORMS_WRITE_STATS
- // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
- coded_bits_per_codeword = get_G(frame_parms,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
- get_Qm(mcs),
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
- num_pdcch_symbols,
- frame,
- subframe,
- beamforming_mode);
- } else {
- coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
- }
+ if (eNB_stats) {
+ rewind (gNB_stats);
+ fwrite (stats_buffer, 1, len, gNB_stats);
+ fclose (gNB_stats);
+ }
+
+ #endif
+ pthread_exit((void *)arg);
+ }*/
+ return NULL;
+}
+
+void gNBinitScope(scopeParms_t *p) {
+ //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
+ fl_initialize (p->argc, p->argv, NULL, 0, 0);
+
+ /*
+ form_stats_l2 = create_form_stats_form();
+ fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
+ form_stats = create_form_stats_form();
+ fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
*/
- I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
- Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
+ for(int UE_id=0; UE_idofdm_symbol_size,sizeof(float));
- }
-
- chest_f_abs = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
- freq = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
-
- llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
- bit = malloc(coded_bits_per_codeword*sizeof(float));
-
- llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
- bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
-
- rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
- rxsig_t_dB = calloc(nb_antennas_rx,sizeof(float*));
- for (arx=0; arxpbch_vars[eNB_id]->dl_ch_estimates_time;
- chest_f = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
-
- pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
- pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
-
- pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
- pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
- pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
- // pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0
- pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
- //pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
+ static scopeParms_t parms;
+ memcpy(&parms,p,sizeof(parms));
+ pthread_t forms_thread;
+ threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
+static void ueTimeResponse (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Received signal in time domain of receive antenna 0
- if (rxsig_t != NULL) {
- if (rxsig_t[0] != NULL) {
- for (i=0; icommon_vars.rxdata)
+ return;
- fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],samples_per_frame,"","","");
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ int samples_per_frame = frame_parms->samples_per_frame;
+ scopeSample_t **rxsig_t = (scopeSample_t **) phy_vars_ue->common_vars.rxdata;
+ float rxsig_t_dB[samples_per_frame];
+ float time[samples_per_frame];
+
+ if (rxsig_t[0] != NULL) {
+ for (int i=0; irxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
+ for (int arx=1; arxis_synchronized==0) {
- for (ind=0;ind<3;ind++) {
+ //float corr[samples_per_frame];
+ for (int ind=0; ind<3; ind++) {
/*
- if (pss_corr_ue[ind]) {
- for (i=0; ichest_t,time,corr,samples_per_frame,"","","");
- else
- fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
+ if (pss_corr_ue[ind]) {
+ for (i=0; ichest_t,time,corr,samples_per_frame,"","","");
+ else
+ fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
+
+ overlay = 1;
+ }
*/
}
- }
- else {
-
- if (overlay) { //there was a previous overlay
- fl_clear_xyplot(form->chest_t);
- overlay = 0;
- }
+ // if the UE is not synchronized, we can make only the time*power graph
+ }
+}
+
+static void ueChannelResponse (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Channel Impulse Response
- if (chest_t != NULL) {
- ymax = 0;
+ if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time)
+ return;
- if (chest_t[0] !=NULL) {
- for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
- chest_t_abs[0][i] = (float) (chest_t[0][2*i]*chest_t[0][2*i]+chest_t[0][2*i+1]*chest_t[0][2*i+1]);
- time[i] = (float) i;
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ scopeSample_t **chest_t = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time;
+ int ymax = 0;
+ float chest_t_abs[frame_parms->ofdm_symbol_size];
+ float time[frame_parms->ofdm_symbol_size>>3];
- if (chest_t_abs[0][i] > ymax)
- ymax = chest_t_abs[0][i];
- }
+ if (chest_t[0] !=NULL) {
+ for (int i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
+ chest_t_abs[i] = SquaredNorm(chest_t[0][i]);
+ time[i] = (float) i;
- fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
+ if (chest_t_abs[i] > ymax)
+ ymax = chest_t_abs[i];
}
- /*
- for (arx=1; arxofdm_symbol_size>>3); i++) {
- chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]);
- if (chest_t_abs[arx][i] > ymax)
- ymax = chest_t_abs[arx][i];
- }
-
- fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
- fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
- }
- }
- */
- // Avoid flickering effect
- // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work...
- fl_set_xyplot_ybounds(form->chest_t,0,(double) ymax);
- }
+ fl_set_xyplot_data(graph,time,chest_t_abs,(frame_parms->ofdm_symbol_size>>3),"","","");
}
+ for (int arx=1; arxofdm_symbol_size>>3); i++) {
+ chest_t_abs[i] = SquaredNorm(chest_t[arx][i]);
+
+ if (chest_t_abs[i] > ymax)
+ ymax = chest_t_abs[i];
+ }
+
+ fl_add_xyplot_overlay(graph,arx,time,chest_t_abs,(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
+ fl_set_xyplot_overlay_type(graph,arx,FL_DASHED_XYPLOT);
+ }
+ }
+
+ // Avoid flickering effect
+ // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work...
+ fl_set_xyplot_ybounds(graph,0,(double) ymax);
+}
+
+static void uePbchFrequencyResp (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Channel Frequency Response (includes 5 complex sample for filter)
- if (chest_f != NULL) {
- ind = 0;
+ if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates)
+ return;
- for (atx=0; atxofdm_symbol_size; k++) {
- freq[ind] = (float)ind;
- Re = (float)(chest_f[(atx<<1)+arx][6144+(2*k)]);
- Im = (float)(chest_f[(atx<<1)+arx][6144+(2*k)+1]);
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB;
+ scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
+ int ind = 0;
+ float chest_f_abs[frame_parms->ofdm_symbol_size];
+ float freq[frame_parms->ofdm_symbol_size];
- chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
- ind++;
- }
+ for (int atx=0; atxofdm_symbol_size; k++) {
+ freq[ind] = (float)ind;
+ chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
+ ind++;
}
}
}
-
- // tx antenna 0
- //fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
- //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
- // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
- //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
- fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
-
- /*
- for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
-
- // other tx antennas
- if (nb_antennas_tx > 1) {
- if (nb_antennas_rx > 1) {
- for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- } else { // 1 rx antenna
- atx=1;
- arx=0;
- fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- */
}
-
+
+ // tx antenna 0
+ //fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
+ // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
+ //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ fl_set_xyplot_data(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
+}
+
+static void uePbchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PBCH LLRs
- if (pbch_llr != NULL) {
- for (i=0; i<864; i++) {
- llr_pbch[i] = (float) pbch_llr[i];
- bit_pbch[i] = (float) i;
- }
+ if ( !phy_vars_ue->pbch_vars[eNB_id]->llr)
+ return;
- fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,864,"","","");
+ int16_t *pbch_llr = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
+ float llr_pbch[864], bit_pbch[864];
+
+ for (int i=0; i<864; i++) {
+ llr_pbch[i] = (float) pbch_llr[i];
+ bit_pbch[i] = (float) i;
}
- first_symbol=1;
+ fl_set_xyplot_data(graph,bit_pbch,llr_pbch,864,"","","");
+}
+static void uePbchIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PBCH I/Q of MF Output
- if (pbch_comp!=NULL) {
- for (symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
- if (symbol == 2 || symbol == 6)
- nb_re = 72;
- else
- nb_re = 180;
- for (i=0; ipbch_vars[eNB_id]->rxdataF_comp[0])
+ return;
+
+ int16_t *pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
+ localBuff(I,180*3);
+ localBuff(Q,180*3);
+ int first_symbol=1;
+ int base=0;
+
+ for (int symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
+ int nb_re;
+
+ if (symbol == 2 || symbol == 6)
+ nb_re = 72;
+ else
+ nb_re = 180;
+
+ AssertFatal(base+nb_re<180*3,"");
+
+ for (int i=0; ipbch_comp,I,Q,432,"","","");
+
+ base+=nb_re;
}
+ fl_set_xyplot_data(graph,I,Q,base,"","","");
+}
+
+static void uePcchLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDCCH LLRs
- if (pdcch_llr != NULL) {
- for (i=0; i<100; i++) { //12*frame_parms->N_RB_DL*2*num_pdcch_symbols
- llr_pdcch[i] = (float) pdcch_llr[2*24*9 +i];
- bit_pdcch[i] = (float) i;
- }
+ if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
+ return;
- fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
- }
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx;
+ scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
+ int ind = 0;
+ float chest_f_abs[frame_parms->ofdm_symbol_size];
+ float freq[frame_parms->ofdm_symbol_size];
- // PDCCH I/Q of MF Output
- if (pdcch_comp!=NULL) {
- for (i=0; i<100; i++) {
- I[i] = pdcch_comp[2*50*12+2*i];
- Q[i] = pdcch_comp[2*50*12+2*i+1];
- }
- fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
- }
-
- // PDSCH LLRs
- if (pdsch_llr != NULL) {
- for (i=0; ipdsch_llr,0,coded_bits_per_codeword);
- fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","","");
- }
-
- first_symbol = 2;
- ind = 0;
- // PDSCH I/Q of MF Output
- if (pdsch_comp!=NULL) {
- for (symbol=0;symbolN_RB_DL*12+i) ];
- Q[ind] = pdsch_comp[2*((first_symbol+symbol)*frame_parms->N_RB_DL*12+i)+1];
- ind++;
+ for (int atx=0; atxofdm_symbol_size; k++) {
+ freq[ind] = (float)ind;
+ chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
+ ind++;
+ }
}
}
-
- fl_set_xyplot_data(form->pdsch_comp,I,Q,nb_symb_sch*nb_rb_pdsch*12,"","","");
}
+
+ // tx antenna 0
+ //fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
+ // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
+ //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ fl_set_xyplot_data(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
+}
+
+static void uePcchIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PDCCH I/Q of MF Output
+ if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
+ return;
+
+ int nb=12*273*4; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
+ localBuff(I,nb*RX_NB_TH_MAX);
+ localBuff(Q,nb*RX_NB_TH_MAX);
+ int base=0;
+
+ for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
+ int16_t *pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->rxdataF_comp[0];
+
+ for (int i=0; i< nb; i++) {
+ I[base+i] = pdcch_comp[i*2];
+ Q[base+i] = pdcch_comp[i*2+1];
+ }
+
+ base+=nb;
+ }
+
+ fl_set_xyplot_data(graph,I,Q,base,"","","");
+}
+
+static void uePdschLLR (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PDSCH LLRs
+ if (!phy_vars_ue->pdsch_vars[0][eNB_id]->llr[0])
+ return;
+
+ int num_re = 4500;
+ int Qm = 2;
+ int coded_bits_per_codeword = num_re*Qm;
+ localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX);
+ localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX);
+ int base=0;
+
+ for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
+ int16_t *pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->llr[0]; // stream 0
+
+ for (int i=0; ipdsch_llr,0,coded_bits_per_codeword);
+ fl_set_xyplot_data(graph,bit,llr,base,"","","");
+}
+
+static void uePdschIQ (FL_OBJECT *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
+ // PDSCH I/Q of MF Output
+ if (!phy_vars_ue->pdsch_vars[0][eNB_id]->rxdataF_comp0[0])
+ return;
+
+ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ int sz=7*2*frame_parms->N_RB_DL*12; // size of the malloced buffer
+ localBuff(I,sz*RX_NB_TH_MAX);
+ localBuff(Q,sz*RX_NB_TH_MAX);
+ int base=0;
+
+ for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
+ int16_t *pdsch_comp = (int16_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->rxdataF_comp0[0];
+
+ for (int s=0; s tput_ue_max[UE_id]) {
- tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
+ tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
}
fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
*/
-
- fl_check_forms();
-
- free(time);
- free(corr);
- for (arx=0; arxphy_scope = fl_bgn_form( FL_NO_BOX, 800, 900 );
+ // This the whole UI box
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" );
+ fl_set_object_color( obj, FL_BLACK, FL_BLACK );
+ // Received signal
+ fdui->graph[0] = nrUEcommonGraph(ueTimeResponse,
+ FL_IMPULSE_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)", FL_RED );
+ // Time-domain channel response
+ fdui->graph[1] = nrUEcommonGraph(ueChannelResponse,
+ FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)", FL_RED );
+ // Frequency-domain channel response
+ fdui->graph[2] = nrUEcommonGraph(uePbchFrequencyResp,
+ FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency data (RE, dB)", FL_RED );
+ // LLR of PBCH
+ fdui->graph[3] = nrUEcommonGraph(uePbchLLR,
+ FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN );
+ fl_set_xyplot_xgrid(fdui->graph[3].graph,FL_GRID_MAJOR);
+ // I/Q PBCH comp
+ fdui->graph[4] = nrUEcommonGraph(uePbchIQ,
+ FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output", FL_GREEN );
+ // LLR of PDCCH
+ fdui->graph[5] = nrUEcommonGraph(uePcchLLR,
+ FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)", FL_CYAN );
+ // I/Q PDCCH comp
+ fdui->graph[6] = nrUEcommonGraph(uePcchIQ,
+ FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output", FL_CYAN );
+ // LLR of PDSCH
+ fdui->graph[7] = nrUEcommonGraph(uePdschLLR,
+ FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
+ // I/Q PDSCH comp
+ fdui->graph[8] = nrUEcommonGraph(uePdschIQ,
+ FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output", FL_YELLOW );
+ // Throughput on PDSCH
+ fdui->graph[9] = nrUEcommonGraph(uePdschThroughput,
+ FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]", FL_WHITE );
+ fdui->graph[10].graph=NULL;
+ // Generic UE Button
+ fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
+ fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
+ //openair_daq_vars.use_ia_receiver = 0;
+ fl_set_button(fdui->button_0,0);
+ fl_set_object_label(fdui->button_0, "IA Receiver OFF");
+ fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
+ fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
+ fl_hide_object(fdui->button_0);
+ fl_end_form( );
+ fdui->phy_scope->fdui = fdui;
+ char buf[100];
+ sprintf(buf,"NR DL SCOPE UE %d", ID);
+ fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, buf);
+ return fdui;
+}
+void phy_scope_nrUE(FD_phy_scope_t *form,
+ PHY_VARS_NR_UE *phy_vars_ue,
+ int eNB_id,
+ int UE_id) {
+ static FD_phy_scope_t *remeberForm=NULL;
-// current status is that every UE has a DL scope for a SINGLE eNB (gnb_id=0)
-// at eNB 0, an UL scope for every UE
-FD_phy_scope_gnb *form_gnb[NUMBER_OF_UE_MAX];
+ if (form==NULL)
+ form=remeberForm;
+ else
+ remeberForm=form;
+
+ if (form==NULL)
+ return;
+
+ int i=0;
+
+ while (form->graph[i].graph) {
+ form->graph[i].nrUEfunct(form->graph[i].graph, phy_vars_ue, eNB_id, UE_id);
+ i++;
+ }
+
+ fl_check_forms();
+}
+
+static FD_phy_scope_t *form_nrue[NUMBER_OF_UE_MAX];
+static pthread_t forms_thread;
+
+static void *nrUEscopeThread(void *arg) {
+ PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg;
+ size_t stksize;
+ pthread_attr_t atr;
+ pthread_attr_getstacksize(&atr, &stksize);
+ pthread_attr_setstacksize(&atr,32*1024*1024 );
+
+ while (!oai_exit) {
+ phy_scope_nrUE(form_nrue[0],
+ ue,
+ 0,0);
+ usleep(99*1000);
+ }
+
+ pthread_exit((void *)arg);
+}
+
+void nrUEinitScope(PHY_VARS_NR_UE *ue) {
+ int fl_argc=1;
+ char *name="5G-UE-scope";
+ fl_initialize (&fl_argc, &name, NULL, 0, 0);
+ form_nrue[0] = create_phy_scope_nrue(0);
+ threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
+
+// Kept to put back the functionality soon
+#if 0
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
//char title[255];
-unsigned char scope_enb_num_ue = 1;
//static pthread_t forms_thread; //xforms
-
-
-void reset_stats_gNB(FL_OBJECT *button,
- long arg)
-{
+static void reset_stats_gNB(FL_OBJECT *button,
+ long arg) {
int i,k;
//PHY_VARS_gNB *phy_vars_gNB = RC.gNB[0][0];
for (i=0; idlsch[i][0]->Mlimit; j++) {
- phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
- phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
- phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
- }
- phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
- phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
- phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0;
- phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0;
- phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0;
- phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;*/
- }
- }
-}
-
-
-static void *scope_thread_gNB(void *arg) {
- scopeParms_t * p=(scopeParms_t *) arg;
-//# ifdef ENABLE_XFORMS_WRITE_STATS
-// FILE *gNB_stats = fopen("gNB_stats.txt", "w");
-//#endif
-
- while (!oai_exit) {
- int ue_cnt=0;
-
- for(int UE_id=0; UE_idgNB, p->ru, UE_id);
- ue_cnt++;
+ phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
+ phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
+ phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
}
+ phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
+ phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
+ phy_vars_gNB->UE_stats[i].ulsch_consecutive_errors=0;
+ phy_vars_gNB->UE_stats[i].dlsch_sliding_cnt=0;
+ phy_vars_gNB->UE_stats[i].dlsch_NAK_round0=0;
+ phy_vars_gNB->UE_stats[i].dlsch_mcs_offset=0;*/
}
- sleep(1);
}
-
-// printf("%s",stats_buffer);
-/*#ifdef ENABLE_XFORMS_WRITE_STATS
-
- if (eNB_stats) {
- rewind (gNB_stats);
- fwrite (stats_buffer, 1, len, gNB_stats);
- fclose (gNB_stats);
- }
-
-#endif
- pthread_exit((void *)arg);
-}*/
-
- return NULL;
}
-FD_stats_form * create_form_stats_form( void ) {
+static FD_stats_form *create_form_stats_form(int ID) {
FL_OBJECT *obj;
FD_stats_form *fdui = fl_malloc( sizeof *fdui );
fdui->vdata = fdui->cdata = NULL;
@@ -963,24 +909,8 @@ FD_stats_form * create_form_stats_form( void ) {
fdui->stats_form->fdui = fdui;
return fdui;
}
+#endif
+
+
-void startScope(scopeParms_t * p) {
- //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
- char title[255];
- fl_initialize (p->argc, p->argv, NULL, 0, 0);
- /*
- form_stats_l2 = create_form_stats_form();
- fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
- form_stats = create_form_stats_form();
- fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
- */
-
- for(int UE_id=0; UE_idphy_scope_gnb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
- } // UE_id
- pthread_t forms_thread;
- threadCreate(&forms_thread, scope_thread_gNB, p, "scope", -1, OAI_PRIORITY_RT_LOW);
-}
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h
index 29229d6b12..cf28680a94 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.h
+++ b/openair1/PHY/TOOLS/nr_phy_scope.h
@@ -26,7 +26,6 @@
#include
#include
#include
-#include
#include "common/ran_context.h"
#include
#include
@@ -35,55 +34,15 @@
//#include "PHY/impl_defs_top.h"
#include "PHY/defs_nr_UE.h"
-/* Forms and Objects */
-typedef struct {
- FL_FORM * phy_scope_gnb;
- FL_OBJECT * rxsig_t;
- FL_OBJECT * chest_f;
- FL_OBJECT * chest_t;
- FL_OBJECT * pusch_comp;
- FL_OBJECT * pucch_comp;
- FL_OBJECT * pucch_comp1;
- FL_OBJECT * pusch_llr;
- FL_OBJECT * pusch_tput;
- FL_OBJECT * button_0;
-} FD_phy_scope_gnb;
-
-typedef struct {
- FL_FORM * phy_scope_nrue;
- FL_OBJECT * rxsig_t;
- FL_OBJECT * chest_f;
- FL_OBJECT * chest_t;
- FL_OBJECT * pbch_comp;
- FL_OBJECT * pbch_llr;
- FL_OBJECT * pdcch_comp;
- FL_OBJECT * pdcch_llr;
- FL_OBJECT * pdsch_comp;
- FL_OBJECT * pdsch_llr;
- FL_OBJECT * pdsch_comp1;
- FL_OBJECT * pdsch_llr1;
- FL_OBJECT * pdsch_tput;
- FL_OBJECT * button_0;
-} FD_phy_scope_nrue;
-
typedef struct {
int *argc;
char **argv;
- RU_t* ru;
+ RU_t *ru;
PHY_VARS_gNB *gNB;
} scopeParms_t;
-extern unsigned char scope_enb_num_ue;
-FD_phy_scope_nrue * create_phy_scope_nrue( void );
-
-void phy_scope_nrUE(FD_phy_scope_nrue *form,
- PHY_VARS_NR_UE *phy_vars_ue,
- int eNB_id,
- int UE_id,
- uint8_t subframe);
-
-
-void startScope(scopeParms_t * p);
+void gNBinitScope(scopeParms_t *p);
+void nrUEinitScope(PHY_VARS_NR_UE *ue);
extern RAN_CONTEXT_t RC;
#endif
diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c
index bd516cd1e0..bb8c46592c 100644
--- a/openair1/PHY/TOOLS/oai_dfts.c
+++ b/openair1/PHY/TOOLS/oai_dfts.c
@@ -6061,19 +6061,118 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
}
int16_t twa36864[24576] __attribute__((aligned(32)));
-int16_t twb36884[24576] __attribute__((aligned(32)));
+int16_t twb36864[24576] __attribute__((aligned(32)));
+
// 12288 x 3
void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][12288] __attribute__((aligned(32)));
+ uint32_t tmpo[3][12288] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<12288; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ dft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ dft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ dft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ if (LOG_DUMPFLAG(DEBUG_DFT)) {
+ LOG_M("dft36864out0.m","o0",tmpo[0],12288,1,1);
+ LOG_M("dft36864out1.m","o1",tmpo[1],12288,1,1);
+ LOG_M("dft36864out2.m","o2",tmpo[2],12288,1,1);
+ }
+
+ for (i=0,i2=0; i<24576; i+=8,i2+=4) {
+ bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i),
+ (simd_q15_t*)(twa36864+i),(simd_q15_t*)(twb36864+i));
+ }
+
+ if (scale==1) {
+ for (i=0; i<576; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
+ if (LOG_DUMPFLAG(DEBUG_DFT)) {
+ LOG_M("out.m","out",output,36864,1,1);
+ }
}
+
void idft36864(int16_t *input, int16_t *output,uint8_t scale) {
- AssertFatal(1==0,"Need to do this ..\n");
+ int i,i2,j;
+ uint32_t tmp[3][12288] __attribute__((aligned(32)));
+ uint32_t tmpo[3][12288] __attribute__((aligned(32)));
+ simd_q15_t *y128p=(simd_q15_t*)output;
+ simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15);
+
+ for (i=0,j=0; i<12288; i++) {
+ tmp[0][i] = ((uint32_t *)input)[j++];
+ tmp[1][i] = ((uint32_t *)input)[j++];
+ tmp[2][i] = ((uint32_t *)input)[j++];
+ }
+
+ idft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
+ idft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
+ idft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
+
+ for (i=0,i2=0; i<24576; i+=8,i2+=4) {
+ ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
+ (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i),
+ (simd_q15_t*)(twa36864+i),(simd_q15_t*)(twb36864+i));
+ }
+ if (scale==1) {
+ for (i=0; i<576; i++) {
+ y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128);
+ y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128);
+ y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128);
+ y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128);
+ y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128);
+ y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128);
+ y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128);
+ y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128);
+ y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128);
+ y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128);
+ y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128);
+ y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128);
+ y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128);
+ y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128);
+ y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128);
+ y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128);
+ y128p+=16;
+ }
+ }
+ _mm_empty();
+ _m_empty();
}
int16_t twa49152[32768] __attribute__((aligned(32)));
int16_t twb49152[32768] __attribute__((aligned(32)));
+
// 16384 x 3
void dft49152(int16_t *input, int16_t *output,uint8_t scale) {
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index ce808eddf9..b8083b5ecf 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -38,8 +38,7 @@
#include "openairinterface5g_limits.h"
#include "PHY/TOOLS/time_meas.h"
#include "defs_common.h"
-#include
-
+#include "nfapi_nr_interface_scf.h"
#define MAX_BANDS_PER_RRU 4
#define MAX_RRU_CONFIG_SIZE 1024
@@ -186,6 +185,16 @@ typedef struct RU_feptx_t_s{
int index;
}RU_feptx_t;
+typedef struct {
+ int frame;
+ int slot;
+ int fmt;
+ int numRA;
+ int prachStartSymbol;
+} RU_PRACH_list_t;
+
+#define NUMBER_OF_NR_RU_PRACH_MAX 8
+
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
struct RU_t_s *ru;
@@ -477,6 +486,8 @@ typedef struct RU_t_s {
int att_tx;
/// flag to indicate precoding operation in RU
int do_precoding;
+ /// FAPI confiuration
+ nfapi_nr_config_request_scf_t config;
/// Frame parameters
struct LTE_DL_FRAME_PARMS *frame_parms;
struct NR_DL_FRAME_PARMS *nr_frame_parms;
@@ -579,6 +590,10 @@ typedef struct RU_t_s {
int32_t *bw_list[NUMBER_OF_eNB_MAX+1];
/// beamforming weight vectors
int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15];
+ /// prach commands
+ RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX];
+ /// mutex for prach_list access
+ pthread_mutex_t prach_list_mutex;
/// received frequency-domain signal for PRACH (IF4p5 RRU)
int16_t **prach_rxsigF;
/// received frequency-domain signal for PRACH BR (IF4p5 RRU)
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index aa794da818..378d89e4ea 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -43,6 +43,8 @@
#include "PHY/CODING/nrLDPC_extern.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
+#include "nfapi_nr_interface_scf.h"
+
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
#define MAX_PUCCH0_NID 8
@@ -52,6 +54,7 @@ typedef struct {
int lut[MAX_PUCCH0_NID][160][14];
} NR_gNB_PUCCH0_LUT_t;
+
typedef struct {
uint32_t pbch_a;
uint32_t pbch_a_interleaved;
@@ -155,6 +158,14 @@ typedef struct {
int16_t sqrt_rho_b;
} NR_gNB_DLSCH_t;
+typedef struct {
+ int frame;
+ int slot;
+ nfapi_nr_prach_pdu_t pdu;
+} gNB_PRACH_list_t;
+
+#define NUMBER_OF_NR_PRACH_MAX 8
+
typedef struct {
/// \brief ?.
/// first index: ? [0..1023] (hard coded)
@@ -165,6 +176,7 @@ typedef struct {
int16_t **rxsigF;
/// \brief local buffer to compute prach_ifft
int32_t *prach_ifft;
+ gNB_PRACH_list_t list[NUMBER_OF_NR_PRACH_MAX];
} NR_gNB_PRACH;
typedef struct {
@@ -172,8 +184,8 @@ typedef struct {
nfapi_nr_pusch_pdu_t ulsch_pdu;
/// Frame where current HARQ round was sent
uint32_t frame;
- /// Subframe where current HARQ round was sent
- uint32_t subframe;
+ /// Slot where current HARQ round was sent
+ uint32_t slot;
/// Index of current HARQ round for this DLSCH
uint8_t round;
/// Last TPC command
@@ -667,6 +679,8 @@ typedef struct PHY_VARS_gNB_s {
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords]
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
NR_gNB_DLSCH_t *dlsch_PCH;
+ t_nrPolar_params *uci_polarParams;
+
uint8_t pbch_configured;
char gNB_generate_rar;
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index b2d6a75265..9bdf892ceb 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -782,6 +782,8 @@ typedef struct {
int16_t amp;
int16_t *prachF;
int16_t *prach;
+ fapi_nr_ul_config_prach_pdu prach_pdu;
+ uint8_t prach_Config_enabled;
} NR_UE_PRACH;
// structure used for multiple SSB detection
@@ -882,8 +884,6 @@ typedef struct {
fapi_nr_config_request_t nrUE_config;
- uint16_t frame_gap;
-
// the following structures are not part of PHY_vars_UE anymore as it is not thread safe. They are now on the stack of the functions that actually need them
//nr_downlink_indication_t dl_indication;
@@ -930,7 +930,7 @@ typedef struct {
uint8_t pucch_sel[10];
uint8_t pucch_payload[22];
- UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX];
+ UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
/// cell-specific reference symbols
uint32_t lte_gold_table[7][20][2][14];
@@ -965,12 +965,13 @@ typedef struct {
char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX];
+ unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_gNB_MAX];
+ uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_gNB_MAX];
+ unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_gNB_MAX];
+ uint8_t Msg3_startSymbol[NUMBER_OF_CONNECTED_gNB_MAX];
+ uint8_t Msg3_Length[NUMBER_OF_CONNECTED_gNB_MAX];
-
- unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX];
- uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX];
- unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX];
- PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX];
+ NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX];
int turbo_iterations, turbo_cntl_iterations;
/// \brief ?.
/// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
@@ -1005,8 +1006,6 @@ typedef struct {
int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX];
unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX];
- uint8_t generate_prach;
- uint8_t generate_nr_prach;
uint8_t prach_cnt;
uint8_t prach_PreambleIndex;
// uint8_t prach_timer;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index ccc79b7d47..584962c55c 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -198,30 +198,34 @@ typedef struct {
nr_reg_t reg_list[NR_NB_REG_PER_CCE];
} nr_cce_t;
-
-/// PRACH-ConfigInfo from 38.331 RRC spec
typedef struct {
- /// Parameter: prach-ConfigurationIndex, see TS 38.211 (6.3.3.2).
- uint8_t prach_ConfigIndex;
- /// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set.
- uint8_t highSpeedFlag;
- /// Restricted Set Config (type A=0 , type B=1) TS 38.211 (6.3.3.1)
- uint8_t restrictedSetConfig;
- /// 38.211 (NCS 38.211 6.3.3.1).
- uint8_t zeroCorrelationZoneConfig;
- /// see TS 38.211 (6.3.3.2).
- uint8_t msg1_frequencystart;
-} NR_PRACH_CONFIG_INFO;
-
-/// PRACH-ConfigSIB or PRACH-Config
-typedef struct {
- /// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2).
- uint16_t rootSequenceIndex;
- /// prach_Config_enabled=1 means enabled.}
- uint8_t prach_Config_enabled;
- /// PRACH Configuration Information
- NR_PRACH_CONFIG_INFO prach_ConfigInfo;
-} NR_PRACH_CONFIG_COMMON;
+ /// PRACH format retrieved from prach_ConfigIndex
+ uint16_t prach_format;
+ /// Preamble index for PRACH (0-63)
+ uint8_t ra_PreambleIndex;
+ /// RACH MaskIndex
+ uint8_t ra_RACH_MaskIndex;
+ /// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step.
+ int ra_PREAMBLE_RECEIVED_TARGET_POWER;
+ /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex
+ uint8_t ra_TDD_map_index;
+ /// RA Preamble Power Ramping Step in dB
+ uint32_t RA_PREAMBLE_POWER_RAMPING_STEP;
+ ///
+ uint8_t RA_PREAMBLE_BACKOFF;
+ ///
+ uint8_t RA_SCALING_FACTOR_BI;
+ ///
+ uint8_t RA_PCMAX;
+ /// Corresponding RA-RNTI for UL-grant
+ uint16_t ra_RNTI;
+ /// Pointer to Msg3 payload for UL-grant
+ uint8_t *Msg3;
+ /// Frame of last completed synch
+ uint8_t sync_frame;
+ /// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync
+ uint8_t init_msg1;
+} NR_PRACH_RESOURCES_t;
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
@@ -313,8 +317,6 @@ struct NR_DL_FRAME_PARMS {
uint8_t nb_antennas_rx;
/// Number of common transmit antenna ports in eNodeB (1 or 2)
uint8_t nb_antenna_ports_gNB;
- /// PRACH_CONFIG
- NR_PRACH_CONFIG_COMMON prach_config_common;
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
lte_prefix_type_t Ncp;
/// shift of pilot position in one RB
@@ -350,9 +352,10 @@ struct NR_DL_FRAME_PARMS {
uint8_t ssb_index;
/// PBCH polar encoder params
t_nrPolar_params pbch_polar_params;
-
};
+
+
#define KHz (1000UL)
#define MHz (1000*KHz)
diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c
index 5c145a3230..40e4a56667 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.c
+++ b/openair1/SCHED_NR/fapi_nr_l1.c
@@ -44,7 +44,7 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
- LOG_I(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
+ LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
}
@@ -144,16 +144,16 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
gNB = RC.gNB[Mod_id];
- uint8_t number_dl_pdu = DL_req->dl_tti_request_body.nPDUs;
- // uint8_t number_ul_pdu = 0;
+ uint8_t number_dl_pdu = (DL_req==NULL) ? 0 : DL_req->dl_tti_request_body.nPDUs;
uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus;
+ uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus;
- // if (UL_tti_req != NULL) number_ul_pdu = UL_tti_req->n_pdus;
-
- LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d%d DL_req:SFN/SLO:%04d%d:dl_pdu:%d tx_req:SFN/SLOT:%04d%d:pdus:%d;\n",
- frame,slot,
- DL_req->SFN,DL_req->Slot,number_dl_pdu,
- TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs);
+ if (DL_req != NULL && TX_req!=NULL)
+ LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n",
+ frame,slot,
+ DL_req->SFN,DL_req->Slot,number_dl_pdu,
+ TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs,
+ number_ul_dci_pdu,number_ul_tti_pdu);
int pdcch_received=0;
gNB->num_pdsch_rnti=0;
@@ -174,6 +174,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n");
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&dl_tti_pdu->pdcch_pdu);
@@ -184,6 +185,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
{
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15;
uint16_t pduIndex = pdsch_pdu_rel15->pduIndex;
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
@@ -194,13 +196,28 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
}
}
- if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t));
+ // if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t));
for (int i=0;iul_dci_pdu_list[i]);
+ handle_nfapi_nr_ul_dci_pdu(gNB, frame, slot, &UL_dci_req->ul_dci_pdu_list[i]);
}
-
+ for (int i = 0; i < number_ul_tti_pdu; i++) {
+ switch (UL_tti_req->pdus_list[i].pdu_type) {
+ case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ // handle_nfapi_nr_pucch_pdu(gNB,frame,slot,UL_tti_req->pdus_list[i].pucch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
+ nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
+ nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
+ break;
+ }
+ }
}
diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c
index 9054ddbae5..a5d459a7c6 100644
--- a/openair1/SCHED_NR/nr_prach_procedures.c
+++ b/openair1/SCHED_NR/nr_prach_procedures.c
@@ -32,7 +32,7 @@
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "nfapi_nr_interface_scf.h"
#include "fapi_nr_l1.h"
#include "nfapi_pnf.h"
@@ -77,15 +77,14 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,
}
}
-
- /* rx_nr_prach(gNB,
+ rx_nr_prach(gNB,
prach_pdu,
frame,
slot,
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]
- );*/
+ );
LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
frame,slot,
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index aefeec43e2..560f47059a 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -520,7 +520,7 @@ void nr_fep0(RU_t *ru, int first_half) {
ru->common.rxdataF[aa],
l,
proc->tti_rx,
- 0,
+ ru->N_TA_offset,
0);
}
}
@@ -642,6 +642,8 @@ void nr_fep_full(RU_t *ru, int slot) {
// if ((fp->frame_type == TDD) &&
// (subframe_select(fp,proc->tti_rx) != NR_UPLINK_SLOT)) return;
+ LOG_D(PHY,"In fep_full for slot = %d\n", proc->tti_rx);
+
start_meas(&ru->ofdm_demod_stats);
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
@@ -655,7 +657,7 @@ void nr_fep_full(RU_t *ru, int slot) {
ru->common.rxdataF[aa],
l,
proc->tti_rx,
- 0,
+ ru->N_TA_offset,
0);
}
}
diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c
index a36cebd6ae..0ccb13fc7c 100644
--- a/openair1/SCHED_NR/phy_frame_config_nr.c
+++ b/openair1/SCHED_NR/phy_frame_config_nr.c
@@ -369,6 +369,73 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti)
}
}
+/*******************************************************************
+*
+* NAME : nr_ue_slot_select
+*
+* DESCRIPTION : function for the UE equivalent to nr_slot_select
+*
+*********************************************************************/
+
+int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) {
+ /* for FFD all slot can be considered as an uplink */
+ int mu = cfg->ssb_config.scs_common, check_slot = 0;
+
+ if (cfg->cell_config.frame_duplex_type == FDD) {
+ return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
+ }
+
+ if (nr_frame%2 == 0) {
+ for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
+ check_slot++;
+ }
+ }
+
+ if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
+ return (NR_UPLINK_SLOT);
+ }
+
+ check_slot = 0;
+
+ for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
+ check_slot++;
+ }
+ }
+
+ if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
+ return (NR_DOWNLINK_SLOT);
+ } else {
+ return (NR_MIXED_SLOT);
+ }
+ } else {
+ for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<num_pdsch_rnti);
for (int i=0; inum_pdsch_rnti; i++) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
+ LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti);
nr_generate_pdsch(gNB->dlsch[i][0],
gNB->nr_gold_pdsch_dmrs[slot],
gNB->common_vars.txdataF,
@@ -209,8 +208,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1);
-
- if (do_prach_rx(fp,frame,slot)) L1_nr_prach_procedures(gNB,frame,slot/fp->slots_per_subframe);
*/
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
@@ -218,7 +215,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu;
- uint8_t ret;
+ uint8_t ret, nodata_dmrs = 1;
uint8_t l, number_dmrs_symbols = 0;
uint32_t G;
uint16_t start_symbol, number_symbols, nb_re_dmrs;
@@ -227,9 +224,13 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
number_symbols = pusch_pdu->nr_of_symbols;
for (l = start_symbol; l < start_symbol + number_symbols; l++)
- number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
+ number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
+
+ if (nodata_dmrs)
+ nb_re_dmrs = 12;
+ else
+ nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4);
- nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4);
G = nr_get_G(pusch_pdu->rb_size,
number_symbols,
@@ -238,11 +239,9 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
-
//----------------------------------------------------------
//------------------- ULSCH unscrambling -------------------
//----------------------------------------------------------
-
start_meas(&gNB->ulsch_unscrambling_stats);
nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id]->llr,
G,
@@ -365,6 +364,7 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
// nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
+
for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
nr_slot_fep_ul(&gNB->frame_parms,
gNB->common_vars.rxdata[aa],
@@ -380,67 +380,34 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
- nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req;
- int num_pdus = UL_tti_req->n_pdus;
+ LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
- nfapi_nr_uci_indication_t *uci_indication = &gNB->uci_indication;
- uci_indication->sfn = frame_rx;
- uci_indication->slot = slot_rx;
- uci_indication->num_ucis = 0;
+ for (int ULSCH_id=0;ULSCH_idulsch[ULSCH_id][0];
+ int harq_pid;
+ NR_UL_gNB_HARQ_t *ulsch_harq;
+ if ((ulsch) &&
+ (ulsch->rnti > 0)) {
+ // for for an active HARQ process
+ for (harq_pid=0;harq_pidharq_processes[harq_pid];
+ AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
+ if ((ulsch_harq->status == NR_ACTIVE) &&
+ (ulsch_harq->frame == frame_rx) &&
+ (ulsch_harq->slot == slot_rx) &&
+ (ulsch_harq->handled == 0)){
- LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pdus %d\n",frame_rx,slot_rx,num_pdus);
-
- gNB->UL_INFO.rx_ind.number_of_pdus = 0;
- gNB->UL_INFO.crc_ind.number_crcs = 0;
-
- for (int i = 0; i < num_pdus; i++) {
- switch (UL_tti_req->pdus_list[i].pdu_type) {
- case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
- {
- LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx);
-
- nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
- nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu);
-
- uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST);
- uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id;
- uint8_t symbol_start = pusch_pdu->start_symbol_index;
- uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols;
-
- for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
- nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
- }
- //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
- //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
- nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
- }
- break;
- case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
- {
- LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE\n",frame_rx,slot_rx);
-
- nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[i].pucch_pdu;
- switch (pucch_pdu->format_type) {
- case 0:
- uci_indication->uci_list[uci_indication->num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
- uci_indication->uci_list[uci_indication->num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
- nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci_indication->uci_list[uci_indication->num_ucis].pucch_pdu_format_0_1;
-
- nr_decode_pucch0(gNB,
- slot_rx,
- uci_pdu_format0,
- pucch_pdu);
-
- uci_indication->num_ucis += 1;
- break;
- case 1:
- break;
- case 2:
- break;
- default:
- AssertFatal(1==0,"Only PUCCH format 0,1 and 2 are currently supported\n");
- }
+ uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
+ uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
+ for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
+ nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
+ }
+ //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
+ //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
+ nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
+ break;
+ }
}
}
}
diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h
index 5f54539b71..b393e9566e 100644
--- a/openair1/SCHED_NR/sched_nr.h
+++ b/openair1/SCHED_NR/sched_nr.h
@@ -39,6 +39,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void 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,nfapi_nr_prach_pdu_t *prach_pdu);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
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);
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index e34ce2b6de..c6aea2ec08 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -218,6 +218,15 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
*/
void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+/*! \brief UE PRACH procedures.
+ @param
+ @param
+ @param
+ */
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode);
+
+int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t subframe);
+
#if 0
/*! \brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69.
@param frame_parms Pointer to DL frame parameter descriptor
@@ -322,13 +331,14 @@ uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t SR);
#endif
+
/*! \brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC.
@param Mod_id Local UE index on which to act
@param CC_id Component Carrier Index
- @param eNB_index ID of eNB
+ @param gNB_index ID of gNB
@returns UE mode
*/
-UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
/*! \brief This function implements the power control mechanism for PUCCH from 36.213.
@param phy_vars_ue PHY variables
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 7439c26eb7..f7e03b7dfe 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -34,151 +34,180 @@
#include "fapi_nr_ue_interface.h"
#include "fapi_nr_ue_l1.h"
-//#include "PHY/phy_vars_nr_ue.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/impl_defs_nr.h"
+
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
-int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
-{
-
+int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
if(scheduled_response != NULL){
- /// module id
- module_id_t module_id = scheduled_response->module_id;
- /// component carrier id
- uint8_t cc_id = scheduled_response->CC_id;
+
+ module_id_t module_id = scheduled_response->module_id;
+ uint8_t cc_id = scheduled_response->CC_id, thread_id;
uint32_t i;
- int slot = scheduled_response->slot;
+ int slot = scheduled_response->slot;
+
// Note: we have to handle the thread IDs for this. To be revisited completely.
- uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot];
+ thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot];
+ NR_UE_DLSCH_t *dlsch0 = NULL;
NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
- NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
- //NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
- PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
-
- // PUCCH_ConfigCommon_nr_t *pucch_config_common = PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
- // PUCCH_Config_t *pucch_config_dedicated = PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
if(scheduled_response->dl_config != NULL){
fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
LOG_D(PHY,"Received %d DL pdus\n",dl_config->number_pdus);
pdcch_vars->nb_search_space = 0;
- for(i=0; inumber_pdus; ++i){
- if(dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI){
- fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
- memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
- pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
- LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
- }else{ //FAPI_NR_DL_CONFIG_TYPE_DLSCH
- // dlsch config pdu
+ for (i = 0; i < dl_config->number_pdus; ++i){
- fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
- uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
- dlsch0->current_harq_pid = current_harq_pid;
- dlsch0->active = 1;
- dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
-
- //dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs;
-
- NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
+ if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) {
- dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
- dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
- dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
- dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
- dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
- dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
- dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
- dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
- dlsch0_harq->mcs = dlsch_config_pdu->mcs;
- dlsch0_harq->DCINdi = dlsch_config_pdu->ndi;
- dlsch0_harq->rvidx = dlsch_config_pdu->rv;
- dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
- dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
- dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind;
- dlsch0_harq->Nl=1;
- dlsch0_harq->mcs_table=0;
- dlsch0_harq->status = ACTIVE;
- LOG_D(MAC,">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq->mcs);
+ fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
+ memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
+ pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
+ LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
- }
+ } else {
+
+ if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){
+ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
+ }
+ else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
+ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
+ }
+
+ fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
+ uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
+ NR_DL_UE_HARQ_t *dlsch0_harq;
+
+ dlsch0->current_harq_pid = current_harq_pid;
+ dlsch0->active = 1;
+ dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
+ //dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs;
+ dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
+
+ if (dlsch0_harq){
+
+ dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
+ dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
+ dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
+ dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
+ dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
+ dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
+ dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
+ dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
+ dlsch0_harq->mcs = dlsch_config_pdu->mcs;
+ dlsch0_harq->DCINdi = dlsch_config_pdu->ndi;
+ dlsch0_harq->rvidx = dlsch_config_pdu->rv;
+ dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
+ dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
+ dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind;
+ dlsch0_harq->Nl=1;
+ dlsch0_harq->mcs_table=0;
+ dlsch0_harq->status = ACTIVE;
+ LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
+ }
+ }
}
- }else{
+ } else {
pdcch_vars->nb_search_space = 0;
}
- if(scheduled_response->ul_config != NULL){
+ if (scheduled_response->ul_config != NULL){
+
fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config;
- for(i=0; inumber_pdus; ++i){
- if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH){
- // pusch config pdu
- nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
- uint8_t current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
- nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu;
- memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
+ for (i = 0; i < ul_config->number_pdus; ++i){
- ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
- }
- if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUCCH){
- // pucch config pdu
- fapi_nr_ul_config_pucch_pdu *pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu;
- uint8_t pucch_resource_id = 0; //FIXME!!!
- uint8_t format = 1; // FIXME!!!
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].hoppingId = pucch_config_pdu->hoppingId;
- PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].p0_nominal = pucch_config_pdu->p0_nominal;
- /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
- pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
- pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
- pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
- pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
- pucch_config_common->hoppingId = pucch_config_pdu->hoppingId;
- pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/
- }
- if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PRACH){
- // prach config pdu
- fapi_nr_ul_config_prach_pdu *prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
- /*frame_parms.prach_config_common.rootSequenceIndex = prach_config_pdu->root_sequence_index;
- frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = prach_config_pdu->prach_configuration_index;
- frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = prach_config_pdu->zero_correlation_zone_config;
- frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag = prach_config_pdu->restrictedset_config;
- frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = prach_config_pdu->prach_freq_offset;*/
- prach_resources->ra_PreambleIndex = prach_config_pdu->preamble_index;
- }
+ uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, pucch_resource_id, current_harq_pid, format, gNB_id = 0;
+ /* PRACH */
+ //NR_PRACH_RESOURCES_t *prach_resources;
+ fapi_nr_ul_config_prach_pdu *prach_config_pdu;
+ /* PUSCH */
+ nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu;
+ /* PUCCH */
+ fapi_nr_ul_config_pucch_pdu *pucch_config_pdu;
+ PUCCH_ConfigCommon_nr_t *pucch_config_common_nr;
+ PUCCH_Config_t *pucch_config_dedicated_nr;
+ PUCCH_format_t *format_params;
+
+ switch (pdu_type){
+
+ case (FAPI_NR_UL_CONFIG_TYPE_PUSCH):
+ // pusch config pdu
+ pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
+ current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
+ nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu;
+
+ memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
+
+ ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
+ ulsch0->harq_processes[current_harq_pid]->status = ACTIVE;
+ break;
+
+ case (FAPI_NR_UL_CONFIG_TYPE_PUCCH):
+ // pucch config pdu
+ pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu;
+ pucch_resource_id = 0; //FIXME!!!
+ format = 1; // FIXME!!!
+ pucch_config_common_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
+ pucch_config_dedicated_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
+ format_params = &pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->format_parameters;
+
+ format_params->initialCyclicShift = pucch_config_pdu->initialCyclicShift;
+ format_params->nrofSymbols = pucch_config_pdu->nrofSymbols;
+ format_params->startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
+ format_params->nrofPRBs = pucch_config_pdu->nrofPRBs;
+ format_params->timeDomainOCC = pucch_config_pdu->timeDomainOCC;
+ format_params->occ_length = pucch_config_pdu->occ_length;
+ format_params->occ_Index = pucch_config_pdu->occ_Index;
+
+ pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
+ pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
+ pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
+ pucch_config_dedicated_nr->formatConfig[format - 1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
+ pucch_config_dedicated_nr->formatConfig[format - 1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
+
+ pucch_config_common_nr->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
+ pucch_config_common_nr->hoppingId = pucch_config_pdu->hoppingId;
+ pucch_config_common_nr->p0_nominal = pucch_config_pdu->p0_nominal;
+
+ /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping;
+ pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used
+ pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used
+ pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK;
+ pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping;
+ pucch_config_common->hoppingId = pucch_config_pdu->hoppingId;
+ pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/
+ break;
+
+ case (FAPI_NR_UL_CONFIG_TYPE_PRACH):
+ // prach config pdu
+ //prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[gNB_id];
+ prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
+ memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu));
+ PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_Config_enabled = 1;
+ break;
+
+ default:
+ break;
+ }
}
- }else{
-
+ } else {
}
- if(scheduled_response->tx_request != NULL){
-
- }else{
-
+ if (scheduled_response->tx_request != NULL){
+ } else {
}
}
@@ -189,10 +218,10 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){
fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
-
+
if(phy_config != NULL)
memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
-
+
return 0;
}
diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
index 81b6d373df..a7e78397fe 100644
--- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h
+++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h
@@ -78,6 +78,5 @@ void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms);
void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
-void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mod);
#endif /* PHY_FRAME_CONFIG_NR_H */
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index e5e48ee0ed..8bcd5cbe26 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -53,7 +53,7 @@
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif
-
+#include "executables/softmodem-common.h"
//#define DEBUG_PHY_PROC
#define NR_PDCCH_SCHED
@@ -66,6 +66,7 @@
#endif
#include "LAYER2/NR_MAC_UE/mac_defs.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "common/utils/LOG/log.h"
#ifdef EMOS
@@ -190,14 +191,13 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
exit(-1);
}
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
-//unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
-/*
- unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
- {
+#endif
- int gain_dB = power_dBm - power_max_dBm;
- int amp_x_100;
+unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
+
+int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){
+
+ int gain_dB = power_dBm - power_max_dBm, amp_x_100 = -1;
switch (N_RB_UL) {
case 6:
@@ -219,37 +219,21 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
amp_x_100 = 408*AMP; // 408 = 100*sqrt(100/6)
break;
default:
- LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL);
- //mac_xface->macphy_exit("");
+ LOG_E(PHY, "Unknown PRB size %d\n", N_RB_UL);
+ return (amp_x_100);
break;
}
if (gain_dB < -30) {
- return(amp_x_100/3162);
- } else if (gain_dB>0)
- return(amp_x_100);
+ return (amp_x_100/3162);
+ } else if (gain_dB > 0)
+ return (amp_x_100);
else
- return(amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6)
- }
-*/
+ return (amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6)
-unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
-{
-
- int gain_dB = power_dBm - power_max_dBm;
- double gain_lin;
-
- gain_lin = pow(10,.1*gain_dB);
- if ((nb_rb >0) && (nb_rb <= N_RB_UL)) {
- return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
- }
- else {
- LOG_E(PHY,"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
- //mac_xface->macphy_exit("");
- }
- return(0);
+ return (amp_x_100);
}
-#endif
+#if 0
void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx)
{
@@ -289,107 +273,6 @@ void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
}
-void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
- // for more flexibility
-
- uint8_t i,j,k,s;
- PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
- //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
- for(int l=0; ldlsch[l][i][j]) {
- for(k=0; kdlsch[l][i][j]->harq_processes[k]; k++) {
- ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE;
- for (s=0; s<10; s++) {
- // reset ACK/NACK bit to DTX for all nr_tti_rxs s = 0..9
- ue->dlsch[l][i][j]->harq_ack[s].ack = 2;
- ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0;
- ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff;
- ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff;
- }
- }
- }
- }
-
- //UL HARQ
- if(ue->ulsch[i]) {
- for(k=0; kulsch[i]->harq_processes[k]; k++) {
- ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE;
- //Set NDIs for all UL HARQs to 0
- // ue->ulsch[i]->harq_processes[k]->Ndi = 0;
-
- }
- }
-
- // flush Msg3 buffer
- ue->ulsch_Msg3_active[i] = 0;
-
- }
- }
-}
-
-void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- // if contention resolution fails, go back to PRACH
- PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti = 0;
- LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id);
- //mac_xface->macphy_exit("");
-}
-
-void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- int i;
-
- LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id);
-
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
- PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
-
- for (i=0; i<8; i++) {
- if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) {
- PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE;
- PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0;
- PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0;
- PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0;
- }
- }
-
-
-}
-
-UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
- return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
-
-}
-void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance) {
-
- ue->timing_advance = timing_advance*4;
-
-
-#ifdef DEBUG_PHY_PROC
- /* TODO: fix this log, what is 'HW timing advance'? */
- /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx_rx, ue->timing_advance);*/
- LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
-#endif
-
-}
-
uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
{
@@ -1380,14 +1263,12 @@ void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_
#endif
+UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){
+ return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]);
+}
-void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
-
- // 3GPP TS 38.213 p4.2
- // scale by the scs numerology
- int factor_mu = 1 << mu;
+uint16_t get_bw_scaling(uint16_t bwp_ul_NB_RB){
uint16_t bw_scaling;
-
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
switch (bwp_ul_NB_RB) {
case 32: bw_scaling = 4; break;
@@ -1398,13 +1279,37 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_com
case 273: bw_scaling = 32; break;
default: abort();
}
+ return bw_scaling;
+}
+
+void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
+
+ // 3GPP TS 38.213 p4.2
+ // scale by the scs numerology
+ int factor_mu = 1 << mu;
+ uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (ta_command - 31) * bw_scaling / factor_mu;
- LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %u\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
+ LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %d\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
+}
+
+// WIP
+// - todo: handle TA application as per ch 4.2 TS 38.213
+void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint16_t ta_command) {
+
+ int factor_mu = 1 << ue->frame_parms.numerology_index;
+ uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL;
+ uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
+
+ // Transmission timing adjustment (TS 38.213 p4.2)
+ ue->timing_advance = bw_scaling / factor_mu;
+
+ LOG_D(PHY, "[UE %d] Frame %d Slot %d, Received (RAR) timing advance command %d new value is %u \n", ue->Mod_id, proc->frame_rx, proc->nr_tti_rx, ta_command, ue->timing_advance);
}
#if 0
+
void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t eNB_id,
@@ -2312,11 +2217,12 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
- uint8_t thread_id)
-{
+ uint8_t thread_id){
//int32_t ulsch_start=0;
int slot_tx = proc->nr_tti_tx;
int frame_tx = proc->frame_tx;
+ uint8_t harq_pid = 0;
+ runmode_t mode = normal_txrx;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
@@ -2326,14 +2232,9 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
start_meas(&ue->phy_proc_tx);
#endif
- uint8_t harq_pid = 0; //temporary implementation
-
- nr_ue_ulsch_procedures(ue,
- harq_pid,
- frame_tx,
- slot_tx,
- thread_id,
- gNB_id);
+ if (ue->UE_mode[gNB_id] == PUSCH || get_softmodem_params()->phy_test == 1){
+ if (ue->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->status == ACTIVE)
+ nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, thread_id, gNB_id);
/*
@@ -2345,33 +2246,21 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
} // UE_mode==PUSCH
*/
- LOG_D(PHY, "Sending data \n");
- nr_ue_pusch_common_procedures(ue,
- harq_pid,
- slot_tx,
- thread_id,
- gNB_id,
- &ue->frame_parms);
-
- //LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1);
-
-
-/*
- if ((ue->UE_mode[eNB_id] == PRACH) &&
- (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
-
- // check if we have PRACH opportunity
-
- if (is_prach_subframe(&ue->frame_parms,frame_tx,nr_tti_tx)) {
-
- ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
- }
- } // mode is PRACH
- else {
- ue->generate_prach=0;
+ nr_ue_pusch_common_procedures(ue,
+ harq_pid,
+ slot_tx,
+ thread_id,
+ gNB_id,
+ &ue->frame_parms);
}
-*/
+
+ /* RACH */
+ if (get_softmodem_params()->do_ra==1) {
+ if ((ue->UE_mode[gNB_id] == PRACH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) {
+ nr_ue_prach_procedures(ue, proc, gNB_id, mode);
+ }
+ }
LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
@@ -2381,137 +2270,6 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
}
-
-void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
-
- int frame_tx = proc->frame_tx;
- int nr_tti_tx = proc->nr_tti_tx;
- int prach_power;
- uint16_t preamble_tx=50;
- PRACH_RESOURCES_t prach_resources;
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
-
- ue->generate_nr_prach=0;
- if (ue->mac_enabled==0){
- ue->prach_resources[eNB_id] = &prach_resources;
- ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
- ue->prach_resources[eNB_id]->ra_TDD_map_index = 0;
- }
-
- if (ue->mac_enabled==1){
-
- // ask L2 for RACH transport
- if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
- LOG_D(PHY,"Getting PRACH resources\n");
- //ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,ue->CC_id,frame_tx,eNB_id,nr_tti_tx);
- // LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);
- // LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
- }
-}
-
-if (ue->prach_resources[eNB_id]!=NULL) {
-
- ue->generate_nr_prach=1;
- ue->prach_cnt=0;
-#ifdef SMBV
-ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
-#endif
-
-#ifdef OAI_EMU
- ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
-#endif
-
- if (abstraction_flag == 0) {
-
- LOG_I(PHY,"mode %d\n",mode);
-
- if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
-
- ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id);
- }
- else {
- ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
- ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
- }
-
- LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
- ue->Mod_id,
- frame_tx,
- nr_tti_tx,
- ue->prach_resources[eNB_id]->ra_PreambleIndex,
- get_nr_PL(ue,eNB_id),
- ue->tx_power_dBm[nr_tti_tx],
- ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
- ue->prach_resources[eNB_id]->ra_TDD_map_index,
- ue->prach_resources[eNB_id]->ra_RNTI);
-
- ue->tx_total_RE[nr_tti_tx] = 96;
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
- ue->prach_vars[eNB_id]->amp = nr_get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
- ue->tx_power_max_dBm,
- ue->frame_parms.N_RB_UL,
- 6);
-#else
- ue->prach_vars[eNB_id]->amp = AMP;
-#endif
- if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
- ue->Mod_id,
- proc->frame_rx,
- proc->nr_tti_tx,
- ue->tx_power_dBm[nr_tti_tx],
- ue->prach_vars[eNB_id]->amp);
-
-
- // start_meas(&ue->tx_prach);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
-
-// prach_power = generate_nr_prach(ue,eNB_id,nr_tti_tx,frame_tx);
-prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
- // stop_meas(&ue->tx_prach);
- LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
- ue->Mod_id,
- get_nr_PL(ue,eNB_id),
- ue->tx_power_dBm[nr_tti_tx],
- dB_fixed(prach_power),
- ue->prach_vars[eNB_id]->amp);
- }/* else {
- UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
- UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
- }*/ // commented for compiling as abstraction flag is 0
-
- if (ue->mac_enabled==1){
- //mac_xface->Msg1_transmitted(ue->Mod_id,ue->CC_id,frame_tx,eNB_id);
- }
-
-LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
- ue->Mod_id,frame_tx,nr_tti_tx,eNB_id,
- ue->prach_resources[eNB_id]->ra_PreambleIndex,
- ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id),
- get_nr_PL(ue,eNB_id));
-
-}
-
-
-// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
-if (mode == calib_prach_tx)
- ue->prach_resources[eNB_id]=NULL;
-
-LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n",
- ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt);
-
-ue->prach_cnt++;
-
-if (ue->prach_cnt==3)
- ue->generate_nr_prach=0;
-
-VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
-}
-
/*
void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
{
@@ -2678,7 +2436,7 @@ void restart_phy(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc, uint8_t eNB_id,uint
}
#endif //(0)
-void nr_ue_pbch_procedures(uint8_t eNB_id,
+void nr_ue_pbch_procedures(uint8_t gNB_id,
PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t abstraction_flag)
@@ -2697,20 +2455,26 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
- //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
+ //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,gNB_id);
ret = nr_rx_pbch(ue, proc,
- ue->pbch_vars[eNB_id],
+ ue->pbch_vars[gNB_id],
&ue->frame_parms,
- eNB_id,
+ gNB_id,
(ue->frame_parms.ssb_index)&7,
SISO,
ue->high_speed_flag);
if (ret==0) {
- ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0;
+ ue->pbch_vars[gNB_id]->pdu_errors_conseq = 0;
+ // Switch to PRACH state if it is first PBCH after initial synch and no timing correction is performed
+ if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){
+ ue->UE_mode[gNB_id] = PRACH;
+ ue->prach_resources[gNB_id]->sync_frame = frame_rx;
+ ue->prach_resources[gNB_id]->init_msg1 = 0;
+ }
#ifdef DEBUG_PHY_PROC
uint16_t frame_tx;
@@ -2740,25 +2504,25 @@ void nr_ue_pbch_procedures(uint8_t eNB_id,
exit(-1);
*/
- ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
- ue->pbch_vars[eNB_id]->pdu_errors++;
+ ue->pbch_vars[gNB_id]->pdu_errors_conseq++;
+ ue->pbch_vars[gNB_id]->pdu_errors++;
- if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) {
+ if (ue->pbch_vars[gNB_id]->pdu_errors_conseq>=100) {
LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n");
exit_fun("More that 100 consecutive PBCH errors! Exiting!\n");
}
}
if (frame_rx % 100 == 0) {
- ue->pbch_vars[eNB_id]->pdu_fer = ue->pbch_vars[eNB_id]->pdu_errors - ue->pbch_vars[eNB_id]->pdu_errors_last;
- ue->pbch_vars[eNB_id]->pdu_errors_last = ue->pbch_vars[eNB_id]->pdu_errors;
+ ue->pbch_vars[gNB_id]->pdu_fer = ue->pbch_vars[gNB_id]->pdu_errors - ue->pbch_vars[gNB_id]->pdu_errors_last;
+ ue->pbch_vars[gNB_id]->pdu_errors_last = ue->pbch_vars[gNB_id]->pdu_errors;
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
ue->Mod_id,frame_rx, nr_tti_rx,
- ue->pbch_vars[eNB_id]->pdu_errors,
- ue->pbch_vars[eNB_id]->pdu_errors_conseq);
+ ue->pbch_vars[gNB_id]->pdu_errors,
+ ue->pbch_vars[gNB_id]->pdu_errors_conseq);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
}
@@ -2998,19 +2762,20 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
nr_tti_rx,
&dci_ind);
-#ifdef NR_PDCCH_SCHED_DEBUG
+//#ifdef NR_PDCCH_SCHED_DEBUG
LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt);
-#endif
+//#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
//LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx);
for (int i=0; i rnti %x : format %d\n",
- ue->Mod_id,frame_rx%1024,nr_tti_rx,nr_mode_string[ue->UE_mode[gNB_id]],
- i,
- dci_ind.dci_list[i].rnti,
- dci_ind.dci_list[i].dci_format);
+ LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
+ ue->Mod_id,frame_rx%1024,nr_tti_rx,nr_mode_string[ue->UE_mode[gNB_id]],
+ i + 1,
+ dci_cnt,
+ dci_ind.dci_list[i].rnti,
+ dci_ind.dci_list[i].dci_format);
}
ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dci_received += dci_cnt;
@@ -3259,7 +3024,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
int first_symbol_flag=0;
if (!dlsch0)
- return;
+ return;
if (dlsch0->active == 0)
return;
@@ -3268,9 +3033,9 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
uint16_t BWPStart = dlsch0->harq_processes[harq_pid]->BWPStart;
// uint16_t BWPSize = dlsch0->harq_processes[harq_pid]->BWPSize;
uint16_t pdsch_start_rb = dlsch0->harq_processes[harq_pid]->start_rb;
- uint16_t pdsch_nb_rb = dlsch0->harq_processes[harq_pid]->nb_rb;
- uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
- uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols;
+ uint16_t pdsch_nb_rb = dlsch0->harq_processes[harq_pid]->nb_rb;
+ uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
+ uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols;
LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
@@ -3305,17 +3070,25 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]);
#endif
// process DLSCH received in first slot
- nr_rx_pdsch(ue,
- pdsch,
- eNB_id,
- eNB_id_i,
- proc->frame_rx,
- nr_tti_rx, // nr_tti_rx,
- m,
- first_symbol_flag,
- dual_stream_UE,
- i_mod,
- dlsch0->current_harq_pid);
+ // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed
+ if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0)
+ nr_rx_pdsch(ue,
+ pdsch,
+ eNB_id,
+ eNB_id_i,
+ proc->frame_rx,
+ nr_tti_rx, // nr_tti_rx,
+ m,
+ first_symbol_flag,
+ dual_stream_UE,
+ i_mod,
+ dlsch0->current_harq_pid);
+ else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS)
+ if (pdsch == RA_PDSCH) ue->pdsch_vars_ra[eNB_id]->llr_offset[m]=ue->pdsch_vars_ra[eNB_id]->llr_offset[m-1];
+ else if (pdsch == PDSCH) ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]=ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m-1];
+ else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n");
+ }
+ if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]);
#if DISABLE_LOG_X
@@ -3332,103 +3105,153 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
} // CRNTI active
}
}
-#if 0
-void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
- int frame_rx = proc->frame_rx;
- int nr_tti_rx = proc->nr_tti_rx;
- int timing_advance;
- NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
- int harq_pid = 0;
- uint8_t *rar;
- /*
- uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
- uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
- */
+// WIP fix:
+// - time domain indication hardcoded to 0 for k2 offset
+// - extend TS 38.213 ch 8.3 Msg3 PUSCH
+// - b buffer
+// - ulsch power offset
+// - UE_mode == PUSCH case (should be handled by TA updates)
+// - harq
+// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures
+void nr_process_rar(nr_downlink_indication_t *dl_info) {
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Received RAR mode %d\n",
- ue->Mod_id,
- frame_rx,
- nr_tti_rx, ue->UE_mode[eNB_id]);
+ module_id_t module_id = dl_info->module_id;
+ int cc_id = dl_info->cc_id, frame_rx = dl_info->proc->frame_rx, nr_tti_rx = dl_info->proc->nr_tti_rx, ta_command, k2, delta;
+ uint8_t gNB_index = dl_info->gNB_index; // *rar;
+ //fapi_nr_dci_indication_t *dci_ind = dl_info->dci_ind;
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id];
+ NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[gNB_index];
+ UE_MODE_t UE_mode = ue->UE_mode[gNB_index];
+ NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_index];
+ uint16_t slots_per_frame = ue->frame_parms.slots_per_frame;
+ uint8_t mu_pusch = 1, sliv_S, sliv_L;
+ // definition table j Table 6.1.2.1.1-4
+ uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1;
+ uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1
+ {j, 0,14}, // row index 1
+ {j, 0,12}, // row index 2
+ {j, 0,10}, // row index 3
+ {j, 2,10}, // row index 4
+ {j, 4,10}, // row index 5
+ {j, 4,8}, // row index 6
+ {j, 4,6}, // row index 7
+ {j+1,0,14}, // row index 8
+ {j+1,0,12}, // row index 9
+ {j+1,0,10}, // row index 10
+ {j+2,0,14}, // row index 11
+ {j+2,0,12}, // row index 12
+ {j+2,0,10}, // row index 13
+ {j, 8,6}, // row index 14
+ {j+3,0,14}, // row index 15
+ {j+3,0,10} // row index 16
+ };
+
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Received RAR mode %d\n", module_id, frame_rx, nr_tti_rx, UE_mode);
if (ue->mac_enabled == 1) {
- if ((ue->UE_mode[eNB_id] != PUSCH) &&
- (ue->prach_resources[eNB_id]->Msg3!=NULL)) {
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Invoking MAC for RAR (current preamble %d)\n",
- ue->Mod_id,frame_rx,
- nr_tti_rx,
- ue->prach_resources[eNB_id]->ra_PreambleIndex);
-
- /* timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
- ue->CC_id,
- frame_rx,
- ue->prach_resources[eNB_id]->ra_RNTI,
- dlsch0->harq_processes[0]->b,
- &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
- ue->prach_resources[eNB_id]->ra_PreambleIndex,
- dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
- */
- /*
- ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
- ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
- */
+ if ((UE_mode != PUSCH) && (prach_resources->Msg3 != NULL)) {
- if (timing_advance!=0xffff) {
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_tti_rx, prach_resources->ra_PreambleIndex);
- LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Got rnti %x and timing advance %d from RAR\n",
- ue->Mod_id,
- frame_rx,
- nr_tti_rx,
- ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
- timing_advance);
+ ta_command = nr_ue_process_rar(ue->Mod_id,
+ cc_id,
+ frame_rx,
+ dlsch0->harq_processes[0]->b,
+ &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti,
+ prach_resources->ra_PreambleIndex,
+ dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
- // remember this c-rnti is still a tc-rnti
+ if (ta_command != 0xffff) {
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got Temporary C-RNTI %x and timing advance %d from RAR\n",
+ ue->Mod_id,
+ frame_rx,
+ nr_tti_rx,
+ ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti,
+ ta_command);
- ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti_is_temporary = 1;
-
- //timing_advance = 0;
- nr_process_timing_advance_rar(ue,proc,timing_advance);
-
- if (mode!=debug_prach) {
- ue->ulsch_Msg3_active[eNB_id]=1;
- nr_get_Msg3_alloc(&ue->frame_parms,
- nr_tti_rx,
- frame_rx,
- &ue->ulsch_Msg3_frame[eNB_id],
- &ue->ulsch_Msg3_subframe[eNB_id]);
-
- LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d nr_tti_rx %d: Msg3_frame %d, Msg3_subframe %d\n",
- ue->Mod_id,
- frame_rx,
- nr_tti_rx,
- ue->ulsch_Msg3_frame[eNB_id],
- ue->ulsch_Msg3_subframe[eNB_id]);
- harq_pid = nr_subframe2harq_pid(&ue->frame_parms,
- ue->ulsch_Msg3_frame[eNB_id],
- ue->ulsch_Msg3_subframe[eNB_id]);
- ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
-
- ue->UE_mode[eNB_id] = RA_RESPONSE;
- // ue->Msg3_timer[eNB_id] = 10;
- ue->ulsch[eNB_id]->power_offset = 6;
- ue->ulsch_no_allocation_counter[eNB_id] = 0;
- }
- } else { // PRACH preamble doesn't match RAR
- LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
- ue->Mod_id,
- ue->prach_resources[eNB_id]->ra_PreambleIndex);
+ nr_process_timing_advance_rar(ue, dl_info->proc, ta_command);
+
+ if (ue->mode != debug_prach) {
+ ue->ulsch_Msg3_active[gNB_index] = 1;
+ // TS 38.213 ch 8.3 Msg3 PUSCH
+ // PUSCH time domain resource allocation A for normal CP
+ // TS 38.214 ch 6.1.2.1.1
+ k2 = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][0];
+ sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][1];
+ sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][2];
+
+ switch (mu_pusch) {
+ case 0:
+ delta = 2;
+ break;
+ case 1:
+ delta = 3;
+ break;
+ case 2:
+ delta = 4;
+ break;
+ case 3:
+ delta = 6;
+ break;
+ }
+
+ ue->Msg3_startSymbol[gNB_index] = sliv_S;
+ ue->Msg3_Length[gNB_index] = sliv_L;
+ ue->ulsch_Msg3_subframe[gNB_index] = (nr_tti_rx + k2 + delta) % slots_per_frame;
+ if (nr_tti_rx + k2 + delta > slots_per_frame){
+ ue->ulsch_Msg3_frame[gNB_index] = (frame_rx + 1) % 1024;
+ } else {
+ ue->ulsch_Msg3_frame[gNB_index] = frame_rx;
+ }
+
+ LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n",
+ ue->Mod_id,
+ frame_rx,
+ nr_tti_rx,
+ ue->ulsch_Msg3_frame[gNB_index],
+ ue->ulsch_Msg3_subframe[gNB_index]);
+ // harq_pid = subframe2harq_pid(&ue->frame_parms,
+ // ue->ulsch_Msg3_frame[gNB_index],
+ // ue->ulsch_Msg3_subframe[gNB_index]);
+ // ue->ulsch[gNB_index]->harq_processes[harq_pid]->round = 0;
+ // ue->Msg3_timer[gNB_index] = 10;
+ // ue->ulsch[gNB_index].power_offset = 6;
+ // ue->ulsch_no_allocation_counter[gNB_index] = 0;
+ ue->UE_mode[gNB_index] = RA_RESPONSE;
+ }
+ } else {
+ LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", ue->Mod_id, prach_resources->ra_PreambleIndex);
}
- } // mode != PUSCH
+ }
+ } else {
+ // rar = dlsch0->harq_processes[0]->b+1;
+ // ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
+ // nr_process_timing_advance_rar(ue, dl_info->proc, ta_command);
}
- else {
- rar = dlsch0->harq_processes[0]->b+1;
- timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
- nr_process_timing_advance_rar(ue,proc,timing_advance);
- }
-
}
-#endif
+
+// if contention resolution fails, go back to UE mode PRACH
+void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index) {
+
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
+ ue->UE_mode[gNB_index] = PRACH;
+
+ for (int i=0; i pdcch_vars[i][gNB_index]->pdcch_config[0].rnti = 0;
+ }
+ LOG_E(PHY,"[UE %d] [RAPROC] Random-access procedure fails, going back to PRACH\n", Mod_id);
+}
+
+void nr_ra_succeeded(uint8_t Mod_id,
+ uint8_t CC_id,
+ uint8_t gNB_index){
+ LOG_I(PHY,"[UE %d][RAPROC] RA procedure succeeded. UE set to PUSCH mode\n", Mod_id);
+ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
+ ue->ulsch_Msg3_active[gNB_index] = 0;
+ ue->UE_mode[gNB_index] = PUSCH;
+}
void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
@@ -3448,7 +3271,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
uint8_t is_cw1_active = 0;
//nfapi_nr_config_request_t *cfg = &ue->nrUE_config;
//uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
- uint8_t nb_re_dmrs = 6; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4;
+ uint8_t nb_re_dmrs = 12; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4;
uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value;
uint16_t nb_symb_sch = 9;
nr_downlink_indication_t dl_indication;
@@ -3471,14 +3294,11 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
if (dlsch0==NULL)
AssertFatal(0,"dlsch0 should be defined at this level \n");
-
harq_pid = dlsch0->current_harq_pid;
is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
-
-
if(dlsch1)
is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
@@ -3523,13 +3343,13 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
if (frame_rx < *dlsch_errors)
*dlsch_errors=0;
- if (pdsch==RA_PDSCH) {
+ if (pdsch == RA_PDSCH) {
if (ue->prach_resources[eNB_id]!=NULL)
- dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+ dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
else {
- LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,nr_tti_rx);
- //mac_xface->macphy_exit("prach_resources is NULL");
- return;
+ LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_tti_rx);
+ //mac_xface->macphy_exit("prach_resources is NULL");
+ return;
}
}
@@ -3545,10 +3365,10 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
start_meas(&ue->dlsch_unscrambling_stats);
#endif
nr_dlsch_unscrambling(pdsch_vars->llr[0],
- dlsch0->harq_processes[harq_pid]->G,
- 0,
- ue->frame_parms.Nid_cell,
- dlsch0->rnti);
+ dlsch0->harq_processes[harq_pid]->G,
+ 0,
+ ue->frame_parms.Nid_cell,
+ dlsch0->rnti);
#if UE_TIMING_TRACE
@@ -3629,10 +3449,10 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
start_meas(&ue->dlsch_unscrambling_stats);
#endif
nr_dlsch_unscrambling(pdsch_vars->llr[1],
- dlsch1->harq_processes[harq_pid]->G,
- 0,
- ue->frame_parms.Nid_cell,
- dlsch1->rnti);
+ dlsch1->harq_processes[harq_pid]->G,
+ 0,
+ ue->frame_parms.Nid_cell,
+ dlsch1->rnti);
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_unscrambling_stats);
#endif
@@ -3653,31 +3473,31 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
#ifdef UE_DLSCH_PARALLELISATION
ret1 = nr_dlsch_decoding_mthread(ue,
- proc,
- eNB_id,
- pdsch_vars->llr[1],
- &ue->frame_parms,
- dlsch1,
- dlsch1->harq_processes[harq_pid],
- frame_rx,
- nb_symb_sch,
- nr_tti_rx,
- harq_pid,
- pdsch==PDSCH?1:0,
- dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+ proc,
+ eNB_id,
+ pdsch_vars->llr[1],
+ &ue->frame_parms,
+ dlsch1,
+ dlsch1->harq_processes[harq_pid],
+ frame_rx,
+ nb_symb_sch,
+ nr_tti_rx,
+ harq_pid,
+ pdsch==PDSCH?1:0,
+ dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret1 = %d\n", ret1);
#else
ret1 = nr_dlsch_decoding(ue,
- pdsch_vars->llr[1],
- &ue->frame_parms,
- dlsch1,
- dlsch1->harq_processes[harq_pid],
- frame_rx,
- nb_symb_sch,
- nr_tti_rx,
- harq_pid,
- pdsch==PDSCH?1:0,//proc->decoder_switch,
- dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+ pdsch_vars->llr[1],
+ &ue->frame_parms,
+ dlsch1,
+ dlsch1->harq_processes[harq_pid],
+ frame_rx,
+ nb_symb_sch,
+ nr_tti_rx,
+ harq_pid,
+ pdsch==PDSCH?1:0,//proc->decoder_switch,
+ dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret1 = %d\n", ret1);
printf("start cw1 dlsch decoding\n");
#endif
@@ -3699,35 +3519,46 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
#endif
LOG_I(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
+
+ LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
}
LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_tti_rx);
-
- LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d, TBS expected dlsch1: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS, dlsch1->harq_processes[harq_pid]->TBS);
+ LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS);
if(retmax_ldpc_iterations+1){
- // fill dl_indication message
- dl_indication.module_id = ue->Mod_id;
- dl_indication.cc_id = ue->CC_id;
- dl_indication.gNB_index = eNB_id;
- dl_indication.frame = frame_rx;
- dl_indication.slot = nr_tti_rx;
- dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance
- dl_indication.proc=proc;
+ // fill dl_indication message
+ dl_indication.module_id = ue->Mod_id;
+ dl_indication.cc_id = ue->CC_id;
+ dl_indication.gNB_index = eNB_id;
+ dl_indication.frame = frame_rx;
+ dl_indication.slot = nr_tti_rx;
+ dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance
+ dl_indication.proc=proc;
- //dl_indication.rx_ind->number_pdus
- rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
- rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
- rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
- LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
- rx_ind.number_pdus = 1;
+ //dl_indication.rx_ind->number_pdus
+ switch (pdsch) {
+ case RA_PDSCH:
+ rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_RAR;
+ break;
+ case PDSCH:
+ rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
+ break;
+ default:
+ break;
+ }
- //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now
- dl_indication.dci_ind = NULL; //&ue->dci_ind;
- // send to mac
- if (ue->if_inst && ue->if_inst->dl_indication)
- ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
+ rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
+ rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
+ LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
+ rx_ind.number_pdus = 1;
+
+ //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now
+ dl_indication.dci_ind = NULL; //&ue->dci_ind;
+ // send to mac
+ if (ue->if_inst && ue->if_inst->dl_indication)
+ ue->if_inst->dl_indication(&dl_indication, ul_time_alignment);
}
// TODO CRC check for CW0
@@ -4045,7 +3876,6 @@ void *UE_thread_slot1_dl_processing(void *arg) {
}
//printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_tti_rx,wait);
-
/**** Pdsch Procedure Slot1 ****/
// start slot1 thread for Pdsch Procedure (slot1)
// do procedures for C-RNTI
@@ -4133,7 +3963,6 @@ void *UE_thread_slot1_dl_processing(void *arg) {
#endif
#endif
-
if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("noting to add");
@@ -4182,18 +4011,13 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
int nr_tti_rx = proc->nr_tti_rx;
int slot_pbch;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0];
- NR_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
fapi_nr_config_request_t *cfg = &ue->nrUE_config;
- uint8_t harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid;
- NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
- uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
- uint16_t start_symb_sch = dlsch0_harq->start_symbol;
uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0;
uint8_t dci_cnt = 0;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
-
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
-
+
LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx);
/*
@@ -4201,7 +4025,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
*/
-
int coreset_nb_rb=0;
int coreset_start_rb=0;
if (pdcch_vars->nb_search_space > 0)
@@ -4236,11 +4059,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if (ue->no_timing_correction==0) {
LOG_I(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction);
nr_adjust_synch_ue(fp,
- ue,
- eNB_id,
- nr_tti_rx,
- 0,
- 16384);
+ ue,
+ eNB_id,
+ frame_rx,
+ nr_tti_rx,
+ 0,
+ 16384);
}
}
@@ -4255,10 +4079,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
nr_slot_fep(ue,
- l,
- nr_tti_rx,
- 0,
- 0);
+ l,
+ nr_tti_rx,
+ 0,
+ 0);
// note: this only works if RBs for PDCCH are contigous!
LOG_D(PHY,"pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d\n",
@@ -4285,40 +4109,41 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if (dci_cnt > 0) {
- LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_cnt);
+ LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_tti_rx, dci_cnt);
- } else {
- LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n",ue->Mod_id,frame_rx,nr_tti_rx);
- }
-#endif //NR_PDCCH_SCHED
+ NR_UE_DLSCH_t *dlsch = NULL;
+ if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1){
+ dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0];
+ } else if (ue->dlsch_ra[0]->active == 1){
+ dlsch = ue->dlsch_ra[0];
+ }
+ AssertFatal(dlsch != NULL, "Unsupported mode\n");
+ uint8_t harq_pid = dlsch->current_harq_pid;
+ NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid];
+ uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
+ uint16_t start_symb_sch = dlsch0_harq->start_symbol;
+ int symb_dmrs = -1;
-
- if (dci_cnt > 0){
LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
//to update from pdsch config
- start_symb_sch = dlsch0_harq->start_symbol;
- int symb_dmrs=-1;
+
for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;}
AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n");
LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos);
nr_gold_pdsch(ue,symb_dmrs,0, 1);
-
- nb_symb_sch = dlsch0_harq->nb_symbols;
for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
nr_slot_fep(ue,
- m, //to be updated from higher layer
- nr_tti_rx,
- 0,
- 0);
-
-
+ m, //to be updated from higher layer
+ nr_tti_rx,
+ 0,
+ 0);
}
- //set active for testing, to be removed
- ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 1;
+ } else {
+ LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_tti_rx);
}
- else
- ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
+
+#endif //NR_PDCCH_SCHED
#if UE_TIMING_TRACE
start_meas(&ue->generic_stat);
@@ -4332,7 +4157,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
PDSCH,
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
NULL);
-
+
//printf("phy procedure pdsch start measurement\n");
nr_ue_measurement_procedures(2,ue,proc,eNB_id,nr_tti_rx,mode);
@@ -4344,7 +4169,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
write_output("rxF_comp.m","rxFc",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp0[0][0],fp->N_RB_DL*12*14,1,1);
write_output("rxF_llr.m","rxFllr",ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr[0],(nb_symb_sch-1)*50*12+50*6,1,0);
*/
-
+
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
}
@@ -4352,11 +4177,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
nr_ue_pdsch_procedures(ue,
- proc,
- eNB_id,
- SI_PDSCH,
- ue->dlsch_SI[eNB_id],
- NULL);
+ proc,
+ eNB_id,
+ SI_PDSCH,
+ ue->dlsch_SI[eNB_id],
+ NULL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
}
@@ -4365,11 +4190,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
nr_ue_pdsch_procedures(ue,
- proc,
- eNB_id,
- P_PDSCH,
- ue->dlsch_p[eNB_id],
- NULL);
+ proc,
+ eNB_id,
+ P_PDSCH,
+ ue->dlsch_p[eNB_id],
+ NULL);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
}
@@ -4378,18 +4203,42 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
nr_ue_pdsch_procedures(ue,
- proc,
- eNB_id,
- RA_PDSCH,
- ue->dlsch_ra[eNB_id],
- NULL);
+ proc,
+ eNB_id,
+ RA_PDSCH,
+ ue->dlsch_ra[eNB_id],
+ NULL);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
+ // #if UE_TIMING_TRACE
+ // start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+ // #endif
+
+ nr_ue_dlsch_procedures(ue,
+ proc,
+ eNB_id,
+ RA_PDSCH,
+ ue->dlsch_ra[eNB_id],
+ NULL,
+ &ue->dlsch_ra_errors[eNB_id],
+ mode);
+
+ // #if UE_TIMING_TRACE
+ // stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+ #if DISABLE_LOG_X
+ printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+ printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+ #else
+ LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+ LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+ #endif
+ // #endif
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
}
// do procedures for C-RNTI
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
-
+
LOG_D(PHY, "DLSCH data reception at nr_tti_rx: %d \n \n", nr_tti_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
@@ -4419,6 +4268,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
#endif
+ // deactivate dlsch once dlsch proc is done
+ ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
}
@@ -4624,3 +4476,119 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,
return(0);
}
+// WIP
+// todo:
+// - set tx_total_RE
+// - power control as per 38.213 ch 7.4
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) {
+
+ int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power; // tx_amp
+ uint16_t /*preamble_tx = 50,*/ pathloss;
+ uint8_t mod_id = ue->Mod_id;
+ UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id);
+ NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id];
+ uint8_t nr_prach = 0;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
+
+ if (ue->mac_enabled == 0){
+ // prach_resources->ra_PreambleIndex = preamble_tx;
+ prach_resources->ra_TDD_map_index = 0;
+ prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
+ prach_resources->ra_RNTI = 0x1234;
+ nr_prach = 1;
+ } else {
+ // ask L2 for RACH transport
+ if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) {
+ LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx);
+ // flush Msg3 Buffer
+ if (prach_resources->Msg3 == NULL){
+ for(int i = 0; iulsch_Msg3_active[i] = 0;
+ }
+ }
+ nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx);
+ }
+ }
+
+ if (!prach_resources->init_msg1 && (frame_tx > ue->prach_resources[gNB_id]->sync_frame + 150)){
+ ue->prach_cnt = 0;
+ prach_resources->init_msg1 = 1;
+ }
+
+ if (ue->prach_resources[gNB_id] != NULL && nr_prach == 1 && prach_resources->init_msg1) {
+
+ pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id);
+ LOG_D(PHY,"runmode %d\n",runmode);
+
+ if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) {
+ ue->tx_power_dBm[nr_tti_tx] = prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss;
+ }
+
+ LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x\n",
+ ue->Mod_id,
+ frame_tx,
+ nr_tti_tx,
+ prach_resources->ra_PreambleIndex,
+ pathloss,
+ ue->tx_power_dBm[nr_tti_tx],
+ prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER,
+ prach_resources->ra_RNTI);
+
+ //ue->tx_total_RE[nr_tti_tx] = 96; // todo
+ ue->prach_vars[gNB_id]->amp = AMP;
+
+ /* #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+ tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_tti_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL);
+ if (tx_amp != -1)
+ ue->prach_vars[gNB_id]->amp = tx_amp;
+ #else
+ ue->prach_vars[gNB_id]->amp = AMP;
+ #endif */
+
+ if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
+ LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id,
+ proc->frame_rx,
+ proc->nr_tti_tx,
+ ue->tx_power_dBm[nr_tti_tx],
+ ue->prach_vars[gNB_id]->amp);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
+
+ prach_power = generate_nr_prach(ue, gNB_id, nr_tti_tx);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
+
+ LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
+ ue->Mod_id,
+ pathloss,
+ ue->tx_power_dBm[nr_tti_tx],
+ dB_fixed(prach_power),
+ ue->prach_vars[gNB_id]->amp);
+
+ if (ue->mac_enabled == 1)
+ nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id);
+
+ LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d: Generated PRACH Msg1 (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n",
+ ue->Mod_id,
+ frame_tx,
+ nr_tti_tx,
+ gNB_id,
+ prach_resources->ra_PreambleIndex,
+ ue->tx_power_dBm[nr_tti_tx],
+ pathloss);
+
+ LOG_D(PHY,"[UE %d] frame %d nr_tti_tx %d : prach_cnt %d\n", ue->Mod_id, frame_tx, nr_tti_tx, ue->prach_cnt);
+
+ ue->prach_cnt++;
+
+ if (ue->prach_cnt == 3)
+ ue->prach_cnt = 0;
+ }
+
+ // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
+ if (runmode == calib_prach_tx)
+ ue->prach_resources[gNB_id] = NULL;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
+}
diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
index 9632291e67..b51c8afbb0 100644
--- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -104,7 +104,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue,
int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH;
- int16_t PL = get_nr_PL(ue, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */
+ int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */
int16_t delta_F_PUCCH = power_config->deltaF_PUCCH_f[pucch_format];
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index 1b62ff81bf..1b4cbc2264 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -37,7 +37,7 @@
#include "PHY/defs_nr_UE.h"
#include
#include
-#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
#ifndef NO_RAT_NR
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 80b26c0bbd..25813191be 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -40,7 +40,7 @@
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR/sched_nr.h"
#include "openair1/SIMULATION/TOOLS/sim.h"
@@ -428,7 +428,7 @@ int main(int argc, char **argv)
uint8_t is_crnti = 0, llr8_flag = 0;
unsigned int TBS = 8424;
unsigned int available_bits;
- uint8_t nb_re_dmrs = 6;
+ uint8_t nb_re_dmrs = 12; // No data in dmrs symbol
uint16_t length_dmrs = 1;
unsigned char mod_order;
uint16_t rate;
@@ -442,7 +442,7 @@ int main(int argc, char **argv)
mod_order = nr_get_Qm_dl(Imcs, mcs_table);
rate = nr_get_code_rate_dl(Imcs, mcs_table);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
- TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
+ TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
//dlsch->harq_ids[subframe]= 0;
rel15->rbSize = nb_rb;
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 0b51901b05..29d3a67771 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -28,11 +28,9 @@
#include "common/ran_context.h"
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
-#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_extern.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
+#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
+#include "LAYER2/NR_MAC_UE/mac_defs.h"
+#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
@@ -43,7 +41,7 @@
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/sched_nr.h"
@@ -55,7 +53,7 @@
#include "LAYER2/NR_MAC_UE/mac_proto.h"
//#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_asn_constant.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
#include "openair1/SIMULATION/RF/rf.h"
diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
index c9253aeedf..c7ee863c35 100644
--- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
+++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
@@ -1,7 +1,7 @@
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0); }
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
-int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
+//int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); }
int32_t get_uldl_offset(int nr_bandP) { return(0); }
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c
new file mode 100644
index 0000000000..bfb9150868
--- /dev/null
+++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c
@@ -0,0 +1,348 @@
+int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0); }
+int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
+int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
+int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
+//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); }
+int32_t get_uldl_offset(int nr_bandP) { return(0); }
+NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
+int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
+int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file ra_procedures.c
+ * \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15)
+ * \author R. Knopp, Navid Nikaein, Guido Casati
+ * \date 2019
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
+ * \note
+ * \warning
+ */
+
+
+/*
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "PHY_INTERFACE/phy_interface_extern.h"
+#include "SCHED_UE/sched_UE.h"
+#include "COMMON/mac_rrc_primitives.h"
+#include "RRC/LTE/rrc_extern.h"
+#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
+#include "common/utils/LOG/log.h"
+#include "UTIL/OPT/opt.h"
+#include "OCG.h"
+#include "OCG_extern.h"
+#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/
+
+/* Tools */
+#include "SIMULATION/TOOLS/sim.h" // for taus
+
+/* RRC */
+#include "NR_RACH-ConfigCommon.h"
+
+/* PHY */
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+#include "PHY/defs_common.h"
+#include "PHY/defs_nr_common.h"
+#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
+
+/* MAC */
+#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
+#include "LAYER2/MAC/mac.h"
+
+extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
+extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
+
+//extern uint8_t nfapi_mode;
+
+// WIP
+// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
+// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
+void nr_get_prach_resources(module_id_t mod_id,
+ int CC_id,
+ uint8_t gNB_id,
+ uint8_t t_id,
+ uint8_t first_Msg3,
+ NR_PRACH_RESOURCES_t *prach_resources,
+ NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
+ // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo
+
+ int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0;
+ uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size;
+
+ // NR_RSRP_Range_t rsrp_ThresholdSSB; // todo
+
+ ///////////////////////////////////////////////////////////
+ //////////* UE Random Access Resource Selection *//////////
+ ///////////////////////////////////////////////////////////
+
+ // todo:
+ // - switch initialisation cases
+ // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
+ // --- SSB selection, set prach_resources->ra_PreambleIndex
+ // -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000
+ // --- set PREAMBLE_INDEX to ra_preamble_index
+ // --- select the SSB signalled by PDCCH
+ // -- RA initiated for SI request:
+ // --- SSB selection, set prach_resources->ra_PreambleIndex
+
+ // if (rach_ConfigDedicated) { // This is for network controlled Mobility
+ // // operation for contention-free RA resources when:
+ // // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
+ // // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
+ // prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
+ // return;
+ // }
+
+ //////////* Contention-based RA preamble selection *//////////
+ // todo:
+ // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB
+ // - todo determine next available PRACH occasion
+
+ // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
+
+ AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
+
+ nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon;
+
+ Msg3_size = mac->RA_Msg3_size;
+ numberOfRA_Preambles = *nr_rach_ConfigCommon->totalNumberOfRA_Preambles;
+
+ if (!nr_rach_ConfigCommon->groupBconfigured) {
+ noGroupB = 1;
+ } else {
+ // RA preambles group B is configured
+ // - Defining the number of RA preambles in RA Preamble Group A for each SSB */
+ sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
+ switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
+ /* - Threshold to determine the groups of RA preambles */
+ case 0:
+ messageSizeGroupA = 56;
+ break;
+ case 1:
+ messageSizeGroupA = 144;
+ break;
+ case 2:
+ messageSizeGroupA = 208;
+ break;
+ case 3:
+ messageSizeGroupA = 256;
+ break;
+ case 4:
+ messageSizeGroupA = 282;
+ break;
+ case 5:
+ messageSizeGroupA = 480;
+ break;
+ case 6:
+ messageSizeGroupA = 640;
+ break;
+ case 7:
+ messageSizeGroupA = 800;
+ break;
+ case 8:
+ messageSizeGroupA = 1000;
+ break;
+ case 9:
+ messageSizeGroupA = 72;
+ break;
+ default:
+ AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
+ /* todo cases 10 -15*/
+ }
+
+ /* Power offset for preamble selection in dB */
+ messagePowerOffsetGroupB = -9999;
+ switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
+ case 0:
+ messagePowerOffsetGroupB = -9999;
+ break;
+ case 1:
+ messagePowerOffsetGroupB = 0;
+ break;
+ case 2:
+ messagePowerOffsetGroupB = 5;
+ break;
+ case 3:
+ messagePowerOffsetGroupB = 8;
+ break;
+ case 4:
+ messagePowerOffsetGroupB = 10;
+ break;
+ case 5:
+ messagePowerOffsetGroupB = 12;
+ break;
+ case 6:
+ messagePowerOffsetGroupB = 15;
+ break;
+ case 7:
+ messagePowerOffsetGroupB = 18;
+ break;
+ default:
+ AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
+ }
+
+ // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
+ mac->deltaPreamble_Msg3 = 0;
+ deltaPreamble_Msg3 = mac->deltaPreamble_Msg3;
+ }
+
+ PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
+
+ /* Msg3 has not been transmitted yet */
+ if (first_Msg3 == 1) {
+ if (noGroupB == 1) {
+ // use Group A preamble
+ prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
+ mac->RA_usedGroupA = 1;
+ } else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) {
+ // Group B is configured and RA preamble Group A is used
+ // - todo add condition on CCCH_sdu_size for initiation by CCCH
+ prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
+ mac->RA_usedGroupA = 1;
+ } else {
+ // Group B preamble is configured and used
+ // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
+ // the remaining belong to RA Preambles Group B
+ prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
+ mac->RA_usedGroupA = 0;
+ }
+ } else { // Msg3 is being retransmitted
+ if (mac->RA_usedGroupA == 1 && noGroupB == 1) {
+ prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
+ } else if (mac->RA_usedGroupA == 1 && noGroupB == 0){
+ prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
+ } else {
+ prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
+ }
+ }
+
+ // todo determine next available PRACH occasion
+ // - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
+ // - else if SSB is selected above
+ // - else if CSI-RS is selected above
+
+ /////////////////////////////////////////////////////////////////////////////
+ //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
+ /////////////////////////////////////////////////////////////////////////////
+ // todo:
+ // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
+ // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
+ // - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded)
+
+ if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
+ mac->RA_PREAMBLE_TRANSMISSION_COUNTER++;
+
+ prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
+
+ // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
+ // 1) this does not apply to contention-free RA Preamble for beam failure recovery request
+ // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
+
+ switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used
+ case 0:
+ msg1_FDM = 1;
+ break;
+ case 1:
+ msg1_FDM = 2;
+ break;
+ case 2:
+ msg1_FDM = 4;
+ break;
+ case 3:
+ msg1_FDM = 8;
+ break;
+ default:
+ AssertFatal(1 == 0,"Unknown msg1_FDM %lu\n", nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM);
+ }
+
+ prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
+
+ // ra_RNTI computation
+ // - todo: this is for TDD FR1 only
+ // - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier
+ // - f_id: index of the PRACH occasion in the frequency domain
+ // - s_id is starting symbol of the PRACH occasion [0...14]
+ // - t_id is the first slot of the PRACH occasion in a system frame [0...80]
+
+ ul_carrier_id = 0; // NUL
+ f_id = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
+ SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
+ s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5];
+
+ // Pick the first slot of the PRACH occasion in a system frame
+ for (i = 0; i < 10; i++){
+ if (((SFN_nbr & (1 << i)) >> i) == 1){
+ t_id = 2*i;
+ break;
+ }
+ }
+ prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
+ mac->ra_rnti = prach_resources->ra_RNTI;
+
+ LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI);
+}
+
+// TbD: RA_attempt_number not used
+void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
+ AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ mac->ra_state = WAIT_RAR;
+ // Start contention resolution timer
+ mac->RA_attempt_number++;
+}
+
+void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
+ AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+ LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ // start contention resolution timer
+ mac->RA_contention_resolution_cnt = 0;
+ mac->RA_contention_resolution_timer_active = 1;
+}
+
+/////////////////////////////////////////////////////////////////////////
+///////* Random Access Preamble Initialization (5.1.1 TS 38.321) *///////
+/////////////////////////////////////////////////////////////////////////
+/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300)
+/// Only one RA procedure is ongoing at any point in time in a MAC entity
+/// the RA procedure on a SCell shall only be initiated by PDCCH order
+
+// WIP
+// todo TS 38.321:
+// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX
+// - BWP operation (subclause 5.15 TS 38.321)
+// - handle initialization by beam failure recovery
+// - handle initialization by handover
+// - handle transmission on DCCH using PRACH (during handover, or sending SR for example)
+// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader)
+// - fix rrc data req logic
+// - retrieve TBS
+// - add mac_rrc_nr_data_req_ue, etc ...
+// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
+
+
diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
index c7a30f826e..7a465e0ea3 100644
--- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
+++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
@@ -55,6 +55,24 @@ signed char quantize(double D, double x, unsigned char B) {
return ((char) qxd);
}
+
+int8_t
+mac_rrc_data_req_ue(
+ const module_id_t Mod_idP,
+ const int CC_id,
+ const frame_t frameP,
+ const rb_id_t Srb_id,
+ const uint8_t Nb_tb,
+ uint8_t *const buffer_pP,
+ const mac_enb_index_t eNB_indexP,
+ const uint8_t mbsfn_sync_area
+ ) { return(0);}
+
+int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
+//NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
+int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
+
+
void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL,int N_RB_UL,int mu_dl,int mu_ul) {
*scc->physCellId=0; \
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 9d14391f71..8030bdf1e2 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -37,7 +37,7 @@
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/phy_vars.h"
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 2ad89ce897..5fddf3290d 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
@@ -35,114 +36,85 @@
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "PHY/phy_vars_nr_ue.h"
-
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
+#include "nr_unitary_defs.h"
#include "OCG_vars.h"
-#include
+#define NR_PRACH_DEBUG 1
+#define PRACH_WRITE_OUTPUT_DEBUG 1
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
RU_t *ru;
-
double cpuf;
-
extern uint16_t prach_root_sequence_map0_3[838];
-
-void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
-
uint16_t NB_UE_INST=1;
-volatile int oai_exit=0;
-
-void exit_function(const char* file, const char* function, const int line,const char *s) {
- const char * msg= s==NULL ? "no comment": s;
- printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
- exit(-1);
-}
-
-
-int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe) {
- AssertFatal(1==0,"Shouldn't be here ...\n");
- return 0;
-}
-
-uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
- sub_frame_t subframe, uint8_t eNB_index,
- uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) {return(0);}
-
-int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
-
openair0_config_t openair0_cfg[MAX_CARDS];
uint8_t nfapi_mode=0;
-NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
-int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
+int sl_ahead = 0;
-uint64_t get_softmodem_optmask(void) {
- return 0;
-}
+//void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
-int main(int argc, char **argv)
-{
+/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
+uint64_t get_softmodem_optmask(void) {return 0;}
+softmodem_params_t *get_softmodem_params(void) {return 0;}
+
+void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
+
+boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
+ const srb_flag_t srb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const rb_id_t rb_idP,
+ const sdu_size_t sdu_buffer_sizeP,
+ mem_block_t *const sdu_buffer_pP) {return(false);}
+
+void nr_ip_over_LTE_DRB_preconfiguration(void){}
+void pdcp_layer_init(void) {}
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
+
+int main(int argc, char **argv){
char c;
-
- int i,aa,aarx;
- double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0,ue_speed0=0.0,ue_speed1=0.0;
- uint8_t snr1set=0;
- uint8_t ue_speed1set=0;
- int **txdata;
- double **s_re,**s_im,**r_re,**r_im;
- double iqim=0.0;
- int trial; //, ntrials=1;
- uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
- uint16_t Nid_cell=0;
-
- uint8_t awgn_flag=0;
- uint8_t hs_flag=0;
- int n_frames=1;
- channel_desc_t *UE2gNB;
- uint32_t tx_lev=0; //,tx_lev_dB;
+ double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0;
+ double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs, bw;
+ int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
+ int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
+ uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format = 0;
+ uint8_t frame = 1, subframe = 19, config_index = 98, prach_sequence_length = 1, num_root_sequences = 16, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
+ uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
+ uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB;
+ uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000;
// int8_t interf1=-19,interf2=-19;
- NR_DL_FRAME_PARMS *frame_parms;
-
- SCM_t channel_model=Rayleigh1;
-
// uint8_t abstraction_flag=0,calibration_flag=0;
// double prach_sinr;
- int N_RB_UL=273;
- uint32_t prach_errors=0;
- uint8_t subframe=9;
- uint16_t preamble_energy_list[64],preamble_tx=50,preamble_delay_list[64];
- PRACH_RESOURCES_t prach_resources;
- //uint8_t prach_fmt;
- //int N_ZC;
- int delay = 0;
- double delay_avg=0;
- double ue_speed = 0;
- int NCS_config = 13,rootSequenceIndex=0;
- int threequarter_fs = 0;
- int mu=1;
- uint64_t SSB_positions=0x01;
+ // uint32_t nsymb;
+ // uint16_t preamble_max, preamble_energy_max;
- int loglvl=OAILOG_INFO;
+ NR_DL_FRAME_PARMS *frame_parms;
+ NR_PRACH_RESOURCES_t prach_resources;
+ nfapi_nr_prach_config_t *prach_config;
+ nfapi_nr_prach_pdu_t *prach_pdu;
+ fapi_nr_prach_config_t *ue_prach_config;
+ fapi_nr_ul_config_prach_pdu *ue_prach_pdu;
+ channel_desc_t *UE2gNB;
+ SCM_t channel_model = Rayleigh1;
cpuf = get_cpu_freq_GHz();
-
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
randominit(0);
-
while ((c = getopt (argc, argv, "hHaA:Cr:p:g:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
switch (c) {
case 'a':
@@ -215,7 +187,7 @@ int main(int argc, char **argv)
break;
default:
- msg("Unsupported channel model!\n");
+ printf("Unsupported channel model!\n");
exit(-1);
}
@@ -231,13 +203,13 @@ int main(int argc, char **argv)
case 's':
snr0 = atof(optarg);
- msg("Setting SNR0 to %f\n",snr0);
+ printf("Setting SNR0 to %f\n",snr0);
break;
case 'S':
snr1 = atof(optarg);
snr1set=1;
- msg("Setting SNR1 to %f\n",snr1);
+ printf("Setting SNR1 to %f\n",snr1);
break;
case 'p':
@@ -263,7 +235,7 @@ int main(int argc, char **argv)
case 'H':
printf("High-Speed Flag enabled\n");
- hs_flag = 1;
+ restrictedSetConfig = 1;
break;
case 'L':
@@ -280,7 +252,7 @@ int main(int argc, char **argv)
if ((transmission_mode!=1) &&
(transmission_mode!=2) &&
(transmission_mode!=6)) {
- msg("Unsupported transmission mode %d\n",transmission_mode);
+ printf("Unsupported transmission mode %d\n",transmission_mode);
exit(-1);
}
@@ -290,7 +262,7 @@ int main(int argc, char **argv)
n_tx=atoi(optarg);
if ((n_tx==0) || (n_tx>2)) {
- msg("Unsupported number of tx antennas %d\n",n_tx);
+ printf("Unsupported number of tx antennas %d\n",n_tx);
exit(-1);
}
@@ -300,7 +272,7 @@ int main(int argc, char **argv)
n_rx=atoi(optarg);
if ((n_rx==0) || (n_rx>2)) {
- msg("Unsupported number of rx antennas %d\n",n_rx);
+ printf("Unsupported number of rx antennas %d\n",n_rx);
exit(-1);
}
@@ -344,20 +316,13 @@ int main(int argc, char **argv)
}
}
+ // Configure log
logInit();
-
set_glog(loglvl);
T_stdout = 1;
-
SET_LOG_DEBUG(PRACH);
- if (snr1set==0) {
- if (n_frames==1)
- snr1 = snr0+.1;
- else
- snr1 = snr0+5.0;
- }
-
+ // Configure gNB and RU
RC.gNB = (PHY_VARS_gNB**) malloc(2*sizeof(PHY_VARS_gNB *));
RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
memset(RC.gNB[0],0,sizeof(PHY_VARS_gNB));
@@ -367,90 +332,201 @@ int main(int argc, char **argv)
memset(RC.ru[0],0,sizeof(RU_t));
RC.nb_RU = 1;
- gNB = RC.gNB[0];
- ru = RC.ru[0];
-
-
- if (ue_speed1set==0) {
- if (n_frames==1)
- ue_speed1 = ue_speed0+10;
- else
- ue_speed1 = ue_speed0+50;
- }
-
- printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
-
- frame_parms = &gNB->frame_parms;
-
-
+ gNB = RC.gNB[0];
+ ru = RC.ru[0];
+ frame_parms = &gNB->frame_parms;
+ prach_config = &gNB->gNB_config.prach_config;
+ prach_pdu = &gNB->prach_vars.list[0].pdu;
+ frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
s_re = malloc(2*sizeof(double*));
s_im = malloc(2*sizeof(double*));
r_re = malloc(2*sizeof(double*));
r_im = malloc(2*sizeof(double*));
- frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
- frame_parms->nb_antennas_tx = n_tx;
- frame_parms->nb_antennas_rx = n_rx;
- frame_parms->N_RB_DL = N_RB_UL;
- frame_parms->N_RB_UL = N_RB_UL;
- frame_parms->threequarter_fs = threequarter_fs;
+ frame_parms->nb_antennas_tx = n_tx;
+ frame_parms->nb_antennas_rx = n_rx;
+ frame_parms->N_RB_DL = N_RB_UL;
+ frame_parms->N_RB_UL = N_RB_UL;
+ frame_parms->threequarter_fs = threequarter_fs;
+ frame_parms->frame_type = TDD;
+ frame_parms->freq_range = nr_FR1;
+ frame_parms->numerology_index = mu;
-
- nr_phy_config_request_sim(gNB,N_RB_UL,N_RB_UL,mu,Nid_cell,SSB_positions);
-
- frame_parms->frame_type = TDD;
- frame_parms->freq_range = nr_FR1;
+ nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
//nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
- printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d,Frame type %s, Frequency Range %s\n",NUMBER_OF_OFDM_CARRIERS,
- frame_parms->Ncp,frame_parms->samples_per_subframe,frame_parms->frame_type == FDD ? "FDD" : "TDD", frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2");
+ printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Frame type %s, Frequency Range %s\n",
+ NUMBER_OF_OFDM_CARRIERS,
+ frame_parms->Ncp,
+ frame_parms->samples_per_subframe,
+ frame_parms->frame_type == FDD ? "FDD" : "TDD",
+ frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2");
- ru->nr_frame_parms=frame_parms;
- ru->if_south = LOCAL_RF;
- ru->nb_tx = n_tx;
- ru->nb_rx = n_rx;
+ ru->nr_frame_parms = frame_parms;
+ ru->if_south = LOCAL_RF;
+ ru->nb_tx = n_tx;
+ ru->nb_rx = n_rx;
+ gNB->gNB_config.carrier_config.num_tx_ant.value = 1;
+ gNB->gNB_config.carrier_config.num_rx_ant.value = 1;
+ gNB->gNB_config.tdd_table.tdd_period.value = 6;
+
+ gNB->gNB_config.prach_config.num_prach_fd_occasions.value = num_prach_fd_occasions;
+ gNB->gNB_config.prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(nfapi_nr_num_prach_fd_occasions_t));
+
+ gNB->proc.slot_rx = subframe;
+
+ get_nr_prach_info_from_index(config_index,
+ (int)frame,
+ (int)subframe,
+ absoluteFrequencyPointA,
+ mu,
+ frame_parms->frame_type,
+ &format,
+ &start_symbol,
+ &N_t_slot,
+ &N_dur);
+
+ format0 = format&0xff; // first column of format from table
+ format1 = (format>>8)&0xff; // second column of format from table
+
+ if (format1 != 0xff) {
+ switch(format0) {
+ case 0xa1:
+ prach_format = 9;
+ break;
+ case 0xa2:
+ prach_format = 10;
+ break;
+ case 0xa3:
+ prach_format = 11;
+ break;
+ default:
+ AssertFatal(1==0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
+ }
+ } else {
+ switch(format0) {
+ case 0xa1:
+ prach_format = 0;
+ break;
+ case 0xa2:
+ prach_format = 1;
+ break;
+ case 0xa3:
+ prach_format = 2;
+ break;
+ case 0xb1:
+ prach_format = 3;
+ break;
+ case 0xb2:
+ prach_format = 4;
+ break;
+ case 0xb3:
+ prach_format = 5;
+ break;
+ case 0xb4:
+ prach_format = 6;
+ break;
+ case 0xc0:
+ prach_format = 7;
+ break;
+ case 0xc2:
+ prach_format = 8;
+ break;
+ case 0:
+ // long formats are handled @ PHY
+ break;
+ case 1:
+ // long formats are handled @ PHY
+ break;
+ case 2:
+ // long formats are handled @ PHY
+ break;
+ case 3:
+ // long formats are handled @ PHY
+ break;
+ default:
+ AssertFatal(1==0, "Invalid PRACH format");
+ }
+ }
+
+ prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value = rootSequenceIndex;
+ prach_config->num_prach_fd_occasions_list[fd_occasion].k1.value = msg1_frequencystart;
+ prach_config->restricted_set_config.value = restrictedSetConfig;
+ prach_config->prach_sequence_length.value = prach_sequence_length;
+ prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = num_root_sequences;
+ prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
+ prach_pdu->prach_format = prach_format;
+
+ memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
RC.nb_nr_L1_inst=1;
phy_init_nr_gNB(gNB,0,0);
nr_phy_init_RU(ru);
- set_tdd_config_nr(&gNB->gNB_config, 5000,
- 7, 6,
- 2, 4);
+ gNB->common_vars.rxdata = ru->common.rxdata;
+ set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
- //configure UE
+ // Configure UE
UE = malloc(sizeof(PHY_VARS_NR_UE));
memset((void*)UE,0,sizeof(PHY_VARS_NR_UE));
PHY_vars_UE_g = malloc(2*sizeof(PHY_VARS_NR_UE**));
PHY_vars_UE_g[0] = malloc(2*sizeof(PHY_VARS_NR_UE*));
PHY_vars_UE_g[0][0] = UE;
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
- if (init_nr_ue_signal(UE, 1, 0) != 0)
- {
+ UE->nrUE_config.prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
+
+ if (init_nr_ue_signal(UE, 1, 0) != 0){
printf("Error at UE NR initialisation\n");
exit(-1);
}
- txdata = UE->common_vars.txdata;
- printf("txdata %p\n",&txdata[0][subframe*frame_parms->samples_per_subframe]);
+ ue_prach_pdu = &UE->prach_vars[0]->prach_pdu;
+ ue_prach_config = &UE->nrUE_config.prach_config;
+ UE->prach_resources[0] = &prach_resources;
+ txdata = UE->common_vars.txdata;
- double fs,bw;
+ UE->prach_vars[0]->amp = AMP;
+ ue_prach_pdu->root_seq_id = rootSequenceIndex;
+ ue_prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
+ ue_prach_pdu->restricted_set = restrictedSetConfig;
+ ue_prach_pdu->freq_msg1 = msg1_frequencystart;
+ ue_prach_pdu->prach_format = prach_format;
+ ue_prach_config->prach_sub_c_spacing = mu;
+ ue_prach_config->prach_sequence_length = prach_sequence_length;
+ ue_prach_config->restricted_set_config = restrictedSetConfig;
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences = num_root_sequences;
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index = rootSequenceIndex;
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].k1 = msg1_frequencystart;
+
+ if (preamble_tx == 99)
+ preamble_tx = (uint16_t)(taus()&0x3f);
+
+ if (n_frames == 1)
+ printf("raPreamble %d\n",preamble_tx);
+
+ UE->prach_resources[0]->ra_PreambleIndex = preamble_tx;
+ UE->prach_resources[0]->init_msg1 = 1;
+
+ // Configure channel
+ bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index);
+ AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n", bw, frame_parms->numerology_index, N_RB_UL);
+
+ if (bw <= 30.72e6)
+ fs = 30.72e6;
+ else if (bw <= 61.44e6)
+ fs = 61.44e6;
+ else if (bw <= 122.88e6)
+ fs = 122.88e6;
- bw = N_RB_UL*(180e3)*(1<frame_parms.numerology_index);
- AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n",bw, gNB->frame_parms.numerology_index,N_RB_UL);
- if (bw <= 30.72e6) fs = 30.72e6;
- else if (bw <= 61.44e6) fs = 61.44e6;
- else if (bw <= 122.88e6) fs = 122.88e6;
LOG_I(PHY,"Running with bandwidth %f Hz, fs %f samp/s, FRAME_LENGTH_COMPLEX_SAMPLES %d\n",bw,fs,FRAME_LENGTH_COMPLEX_SAMPLES);
-
UE2gNB = new_channel_desc_scm(UE->frame_parms.nb_antennas_tx,
gNB->frame_parms.nb_antennas_rx,
channel_model,
- fs,
- bw,
+ fs,
+ bw,
0.0,
delay,
0);
@@ -473,97 +549,82 @@ int main(int argc, char **argv)
bzero(r_im[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
}
- UE->frame_parms.prach_config_common.rootSequenceIndex=rootSequenceIndex;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=98;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.restrictedSetConfig=0;
- UE->frame_parms.prach_config_common.prach_ConfigInfo.msg1_frequencystart=0;
+ // compute PRACH sequence
+ compute_nr_prach_seq(prach_config->prach_sequence_length.value,
+ prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value,
+ prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value,
+ gNB->X_u);
-
- gNB->frame_parms.prach_config_common.rootSequenceIndex=rootSequenceIndex;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=98;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.restrictedSetConfig=0;
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.msg1_frequencystart=0;
-
- gNB->proc.slot_rx = subframe<<1;
-
- gNB->common_vars.rxdata = ru->common.rxdata;
-
-
- compute_nr_prach_seq(gNB->frame_parms.prach_config_common.rootSequenceIndex,
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- gNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
- gNB->frame_parms.frame_type,
- gNB->frame_parms.freq_range,
- gNB->X_u);
-
- compute_nr_prach_seq(UE->frame_parms.prach_config_common.rootSequenceIndex,
- UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
- UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
- UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,
- UE->frame_parms.frame_type,
- UE->frame_parms.freq_range,
- UE->X_u);
-
-
-
- UE->prach_vars[0]->amp = AMP;
-
- UE->prach_resources[0] = &prach_resources;
-
- if (preamble_tx == 99)
- preamble_tx = (uint16_t)(taus()&0x3f);
-
- if (n_frames == 1)
- printf("raPreamble %d\n",preamble_tx);
-
- UE->prach_resources[0]->ra_PreambleIndex = preamble_tx;
- UE->prach_resources[0]->ra_TDD_map_index = 0;
+ compute_nr_prach_seq(ue_prach_config->prach_sequence_length,
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
+ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
+ UE->X_u);
/*tx_lev = generate_nr_prach(UE,
0, //gNB_id,
- subframe,
- 0); //Nf */ //commented for testing purpose
+ subframe); */ //commented for testing purpose
UE_nr_rxtx_proc_t proc={0};
- nr_ue_prach_procedures(UE,&proc,0,0,0);
-
+ proc.frame_tx = frame;
+ proc.nr_tti_tx = subframe;
+ nr_ue_prach_procedures(UE,&proc,0,0);
/* tx_lev_dB not used later, no need to set */
//tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
- LOG_M("txsig0.m","txs0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1);
- //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1);
+ if (mu == 0)
+ samp_count = frame_parms->samples_per_subframe;
+ else
+ samp_count = (subframe%(frame_parms->slots_per_subframe/2)) ? frame_parms->samples_per_slotN0 : frame_parms->samples_per_slot0;
+
+ prach_start = subframe*samp_count - UE->N_TA_offset;
+
+ #ifdef NR_PRACH_DEBUG
+ LOG_M("txsig0.m", "txs0", &txdata[0][prach_start], samp_count, 1, 1);
+ //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1);
+ #endif
// multipath channel
- dump_nr_prach_config(&gNB->frame_parms,subframe);
+ // dump_nr_prach_config(&gNB->frame_parms,subframe);
- for (i=0; i<2*frame_parms->samples_per_subframe; i++) {
+ for (i = 0; i < samp_count<<1; i++) {
for (aa=0; aa<1; aa++) {
if (awgn_flag == 0) {
- s_re[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]);
- s_im[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]);
+ s_re[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
+ s_im[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
} else {
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
if (aa==0) {
- r_re[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]);
- r_im[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]);
+ r_re[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
+ r_im[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
} else {
- r_re[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]);
- r_im[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]);
+ r_re[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
+ r_im[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
}
}
}
}
}
+ if (snr1set == 0) {
+ if (n_frames == 1)
+ snr1 = snr0 + .1;
+ else
+ snr1 = snr0 + 5.0;
+ }
+ printf("SNR0 %f, SNR1 %f\n", snr0, snr1);
- for (SNR=snr0; SNRget_samples_per_slot(subframe,frame_parms);
+
+ for (SNR=snr0; SNRsamples_per_subframe,0);
+ multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_tti<<1, 0);
}
if (n_frames==1) {
@@ -594,55 +655,51 @@ int main(int argc, char **argv)
10*log10(tx_lev));
}
- for (i=0; isamples_per_subframe; i++) {
- for (aa=0; aaframe_parms.nb_antennas_rx; aa++) {
-
- ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
- ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+ for (i = 0; i< frame_parms->get_samples_per_slot(subframe,frame_parms); i++) {
+ for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
+ ((short*) &gNB->common_vars.rxdata[aa][rx_prach_start])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
+ ((short*) &gNB->common_vars.rxdata[aa][rx_prach_start])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
}
}
- uint16_t preamble_rx;
- rx_nr_prach_ru(ru,
- 0,
- subframe);
- gNB->prach_vars.rxsigF = ru->prach_rxsigF;
- rx_nr_prach(gNB,
- 0,
- subframe,
- &preamble_rx,
- preamble_energy_list,
- preamble_delay_list);
-
- if (preamble_rx!=preamble_tx)
+ rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, frame, subframe);
+
+ gNB->prach_vars.rxsigF = ru->prach_rxsigF;
+
+ rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
+
+ printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx);
+
+ if (preamble_rx != preamble_tx)
prach_errors++;
- else {
- delay_avg += (double)preamble_delay_list[preamble_tx];
- }
+ else
+ delay_avg += (double)preamble_delay;
+
+ N_ZC = (prach_sequence_length) ? 139 : 839;
if (n_frames==1) {
- printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy_list[0],preamble_delay_list[0]);
-
-
- LOG_M("prach0.m","prach0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1);
- LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0],24576,1,1);
- LOG_M("rxsig0.m","rxs0",
- &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe],
- frame_parms->samples_per_subframe,1,1);
- LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0],839*4,1,1);
- LOG_M("prach_preamble.m","prachp",&gNB->X_u[0],839,1,1);
+ printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy,preamble_delay);
+ #ifdef NR_PRACH_DEBUG
+ LOG_M("prach0.m","prach0", &txdata[0][prach_start], samp_count, 1, 1);
+ LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1);
+ LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][rx_prach_start], frame_parms->samples_per_subframe, 1, 1);
+ //LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][rx_prach_start], frame_parms->samples_per_subframe, 1, 1);
+ LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0], N_ZC, 1, 1);
+ LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
+ LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
+ #endif
}
}
-
- printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors));
- //printf("(%f,%f)\n",ue_speed,(double)prach_errors/(double)n_frames);
+ printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors));
+ if (prach_errors)
+ break;
} // UE Speed loop
-
- //printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors));
- // printf("(%f,%f)\n",SNR,(double)prach_errors/(double)n_frames);
+ if (!prach_errors) {
+ printf("PRACH test OK\n");
+ break;
+ }
} //SNR loop
-
for (i=0; i<2; i++) {
free(s_re[i]);
free(s_im[i]);
@@ -655,17 +712,5 @@ int main(int argc, char **argv)
free(r_re);
free(r_im);
-
return(0);
-
}
-
-
-
-/*
- for (i=1;i<4;i++)
- memcpy((void *)&PHY_vars->tx_vars[0].TX_DMA_BUFFER[i*12*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*2],
- (void *)&PHY_vars->tx_vars[0].TX_DMA_BUFFER[0],
- 12*OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX*2);
-*/
-
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index a754df4763..dc5089a622 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -37,7 +37,7 @@
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include "SCHED_NR/sched_nr.h"
@@ -84,7 +84,7 @@ int main(int argc, char **argv)
int format=0;
//uint8_t extended_prefix_flag=0;
FILE *input_fd=NULL;
- uint8_t nacktoack_flag=0;
+ //uint8_t nacktoack_flag=0;
int16_t amp=0x7FFF;
int nr_tti_tx=0;
uint64_t actual_payload=0,payload_received;
@@ -283,7 +283,7 @@ int main(int argc, char **argv)
actual_payload=atoi(optarg);
break;
case 'T':
- nacktoack_flag=(uint8_t)atoi(optarg);
+ //nacktoack_flag=(uint8_t)atoi(optarg);
target_error_rate=0.001;
break;
default:
@@ -336,7 +336,7 @@ int main(int argc, char **argv)
}
AssertFatal(((format < 2)&&(nr_bit<3)&&(actual_payload<4)) ||
- ((format == 2)&&(nr_bit>2)&&(nr_bit<12)),"illegal combination format %d, nr_bit %d\n",
+ ((format == 2)&&(nr_bit>2)&&(nr_bit<65)),"illegal combination format %d, nr_bit %d\n",
format,nr_bit);
actual_payload &= ((1<pucch_config_common_nr->pucch_GroupHopping;
uint32_t hopping_id=UE->pucch_config_common_nr->hoppingId;
uint32_t dmrs_scrambling_id = 0, data_scrambling_id=0;
+ //t_nrPolar_params *currentPtr;
+
if(format==0){
// for now we are not considering SR just HARQ-ACK
if (nr_bit ==0)
@@ -467,7 +469,8 @@ int main(int argc, char **argv)
mcs=table2_mcs[actual_payload];
else AssertFatal(1==0,"Either nr_bit %d or sr_flag %d must be non-zero\n", nr_bit, sr_flag);
}
-
+ else if (format == 2 && nr_bit > 11) gNB->uci_polarParams = nr_polar_params(2, nr_bit, nrofPRB, 1, NULL);
+
for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
ack_nack_errors=0;
n_errors = 0;
@@ -498,7 +501,7 @@ int main(int argc, char **argv)
}
int rxlev = signal_energy(&rxdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size);
- // printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
+ if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
if(format==0){
nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu;
nfapi_nr_pucch_pdu_t pucch_pdu;
@@ -506,6 +509,8 @@ int main(int argc, char **argv)
pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1;
pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1;
pucch_pdu.bit_len_harq = nr_bit;
+ pucch_pdu.bit_len_csi_part1 = 0;
+ pucch_pdu.bit_len_csi_part2 = 0;
pucch_pdu.sr_flag = sr_flag;
pucch_pdu.nr_of_symbols = nrofSymbols;
pucch_pdu.hopping_id = hopping_id;
@@ -534,7 +539,9 @@ int main(int argc, char **argv)
pucch_pdu.subcarrier_spacing = 1;
pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1;
pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1;
- pucch_pdu.bit_len_harq = nr_bit;
+ pucch_pdu.bit_len_csi_part1 = nr_bit;
+ pucch_pdu.bit_len_harq = 0;
+ pucch_pdu.bit_len_csi_part2 = 0;
pucch_pdu.sr_flag = 0;
pucch_pdu.nr_of_symbols = nrofSymbols;
pucch_pdu.hopping_id = hopping_id;
@@ -545,14 +552,15 @@ int main(int argc, char **argv)
pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id;
pucch_pdu.data_scrambling_id = data_scrambling_id;
nr_decode_pucch2(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
- int harq_bytes=pucch_pdu.bit_len_harq>>3;
- if ((pucch_pdu.bit_len_harq&7) > 0) harq_bytes++;
- for (int i=0;i>3;
+ if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++;
+ for (int i=0;i>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index 5881b21b5f..a1a00b38f3 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -37,7 +37,7 @@
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
@@ -391,7 +391,7 @@ int main(int argc, char **argv)
mod_order = nr_get_Qm_ul(Imcs, 0);
code_rate = nr_get_code_rate_ul(Imcs, 0);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
- TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
+ TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 169b82bf8d..40653600e8 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -41,11 +41,11 @@
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
-#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/TOOLS/tools_defs.h"
+#include "SCHED_NR/fapi_nr_l1.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR_UE/defs.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
@@ -53,10 +53,12 @@
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
+//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"
+
//#define DEBUG_ULSIM
PHY_VARS_gNB *gNB;
@@ -116,7 +118,7 @@ int main(int argc, char **argv)
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0;
uint8_t n_tx = 1, n_rx = 1;
//uint8_t transmission_mode = 1;
- uint16_t Nid_cell = 0;
+ //uint16_t Nid_cell = 0;
channel_desc_t *gNB2UE;
uint8_t extended_prefix_flag = 0;
//int8_t interf1 = -21, interf2 = -21;
@@ -127,7 +129,7 @@ int main(int argc, char **argv)
int frame_length_complex_samples,frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS *frame_parms;
int loglvl = OAILOG_WARNING;
- uint64_t SSB_positions=0x01;
+ //uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
int start_symbol = 2;
uint16_t nb_rb = 50;
@@ -292,11 +294,11 @@ int main(int argc, char **argv)
break;
case 'M':
- SSB_positions = atoi(optarg);
+ //SSB_positions = atoi(optarg);
break;
case 'N':
- Nid_cell = atoi(optarg);
+ //Nid_cell = atoi(optarg);
break;
case 'R':
@@ -357,7 +359,8 @@ int main(int argc, char **argv)
T_stdout = 1;
get_softmodem_params()->phy_test = 1;
-
+ get_softmodem_params()->do_ra = 0;
+
if (snr1set == 0)
snr1 = snr0 + 10;
@@ -486,7 +489,11 @@ int main(int argc, char **argv)
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0];
//nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu;
- nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req;
+ nfapi_nr_ul_tti_request_t *UL_tti_req = malloc(sizeof(*UL_tti_req));
+ NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO));
+ memset((void*)Sched_INFO,0,sizeof(*Sched_INFO));
+ Sched_INFO->UL_tti_req=UL_tti_req;
+
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu;
NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
@@ -505,7 +512,7 @@ int main(int argc, char **argv)
unsigned int TBS;
uint16_t number_dmrs_symbols = 0;
unsigned int available_bits;
- uint8_t nb_re_dmrs;
+ uint8_t nb_re_dmrs, no_data_in_dmrs = 1;
unsigned char mod_order;
uint16_t code_rate;
uint8_t ptrs_mcs1 = 2;
@@ -604,6 +611,7 @@ int main(int argc, char **argv)
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
+
// --------- setting parameters for UE --------
scheduled_response.module_id = 0;
@@ -638,12 +646,20 @@ int main(int argc, char **argv)
//there are plenty of other parameters that we don't seem to be using for now. e.g.
ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
- nb_re_dmrs = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
+ if(no_data_in_dmrs)
+ nb_re_dmrs = 12;
+ else
+ nb_re_dmrs = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
+
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
- TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, precod_nbr_layers);
+ TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
pusch_pdu->pusch_data.tb_size = TBS>>3;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
+
+ // prepare ULSCH/PUSCH reception
+ nr_schedule_response(Sched_INFO);
+
// set FAPI parameters for UE, put them in the scheduled response and call
nr_ue_scheduled_response(&scheduled_response);
@@ -659,10 +675,10 @@ int main(int argc, char **argv)
////////////////////////////////////////////////////
tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
- txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
+ txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
- txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation
+ txlev_float = (double)txlev; // output of signal_energy is fixed point representation
n_errors = 0;
n_false_positive = 0;
@@ -681,8 +697,8 @@ int main(int argc, char **argv)
//----------------------------------------------------------
for (i=0; inb_antennas_rx; ap++) {
- ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point
- ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP);
+ ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)); // convert to fixed point
+ ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0));
}
}
////////////////////////////////////////////////////////////
diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
index f4835570bf..d344992586 100644
--- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
+++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c
@@ -27,18 +27,20 @@
#include "SIMULATION/RF/rf.h"
#include
-void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length);
+void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length);
double frand_a_b(double a, double b);
-void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int delay);
+void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int delay);
void multipath_tv_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
- uint16_t length,
- uint8_t keep_channel) {
- double complex **tx,**rx,* **H_t,*rx_temp; //, *tv_H_t;
+ uint32_t length,
+ uint8_t keep_channel)
+{
+
+ double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t;
double path_loss = pow(10,desc->path_loss_dB/20);
int i,j,k,dd;
dd = abs(desc->channel_offset);
@@ -126,7 +128,8 @@ void multipath_tv_channel(channel_desc_t *desc,
}
//TODO: make phi_rad a parameter of this function
-void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) {
+void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){
+
int i,j,p,l,k;
double *alpha,*phi_rad,pi=acos(-1),*w_Hz;
alpha = (double *)calloc(desc->nb_paths,sizeof(double));
@@ -193,7 +196,8 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) {
}
// time varying convolution
-void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int dd) {
+void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd){
+
int i,j;
for(i=0; i<((int)nb_samples-dd); i++) {
diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h
index ac46d51174..6071e1e743 100644
--- a/openair1/SIMULATION/TOOLS/sim.h
+++ b/openair1/SIMULATION/TOOLS/sim.h
@@ -426,7 +426,7 @@ void multipath_tv_channel(channel_desc_t *desc,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
- uint16_t length,
+ uint32_t length,
uint8_t keep_channel);
/**@} */
diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h
index 57201721ce..5e5794fc55 100644
--- a/openair2/COMMON/s1ap_messages_def.h
+++ b/openair2/COMMON/s1ap_messages_def.h
@@ -66,6 +66,7 @@ MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_m
MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp)
MESSAGE_DEF(S1AP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_t , s1ap_path_switch_req)
MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_ack_t , s1ap_path_switch_req_ack)
+MESSAGE_DEF(S1AP_E_RAB_MODIFICATION_IND , MESSAGE_PRIORITY_MED, s1ap_e_rab_modification_ind_t , s1ap_e_rab_modification_ind)
/* S1AP -> RRC messages */
MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas )
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index 8e13e35d65..befab4ebdf 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -45,6 +45,7 @@
#define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp
#define S1AP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req
#define S1AP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req_ack
+#define S1AP_E_RAB_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modification_ind
#define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas
#define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
@@ -277,12 +278,26 @@ typedef struct e_rab_tobe_added_s {
uint8_t drb_ID;
/* The transport layer address for the IP packets */
- transport_layer_addr_t eNB_addr;
+ transport_layer_addr_t sgw_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
} e_rab_tobe_added_t;
+typedef struct e_rab_admitted_tobe_added_s {
+ /* Unique e_rab_id for the UE. */
+ uint8_t e_rab_id;
+
+ /* Unique drb_ID for the UE. */
+ uint8_t drb_ID;
+
+ /* The transport layer address for the IP packets */
+ transport_layer_addr_t gnb_addr;
+
+ /* S-GW Tunnel endpoint identifier */
+ uint32_t gtp_teid;
+} e_rab_admitted_tobe_added_t;
+
typedef struct e_rab_tobeswitched_s {
@@ -642,6 +657,27 @@ typedef struct s1ap_path_switch_req_ack_s {
} s1ap_path_switch_req_ack_t;
+typedef struct s1ap_e_rab_modification_ind_s {
+
+ unsigned eNB_ue_s1ap_id:24;
+
+ /* MME UE id */
+ uint32_t mme_ue_s1ap_id;
+
+ /* Number of e_rab setup-ed in the list */
+ uint8_t nb_of_e_rabs_tobemodified;
+
+ uint8_t nb_of_e_rabs_nottobemodified;
+
+ /* list of e_rab setup-ed by RRC layers */
+ e_rab_setup_t e_rabs_tobemodified[S1AP_MAX_E_RAB];
+
+ e_rab_setup_t e_rabs_nottobemodified[S1AP_MAX_E_RAB];
+
+ uint16_t ue_initial_id;
+
+} s1ap_e_rab_modification_ind_t;
+
// S1AP --> RRC messages
typedef struct s1ap_ue_release_command_s {
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index ed3470a7d6..38b3b7d653 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -363,7 +363,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s {
uint8_t nb_e_rabs_admitted_tobeadded;
/* list of e_rab to be added by RRC layers */
- e_rab_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB];
+ e_rab_admitted_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB];
/* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h
index 4c5da80764..94243411e1 100644
--- a/openair2/GNB_APP/RRC_nr_paramsvalues.h
+++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h
@@ -128,12 +128,13 @@
#define GNB_CONFIG_STRING_RARESPONSEWINDOW "ra_ResponseWindow"
#define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSBPR "ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR"
#define GNB_CONFIG_STRING_SSBPERRACHOCCASIONANDCBPREAMBLESPERSSB "ssb_perRACH_OccasionAndCB_PreamblesPerSSB"
-#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER "ra_ContentionResolutionTimer"
-#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB "rsrp_ThresholdSSB"
-#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR"
-#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex"
-#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing"
-#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig"
+#define GNB_CONFIG_STRING_RACONTENTIONRESOLUTIONTIMER "ra_ContentionResolutionTimer"
+#define GNB_CONFIG_STRING_RSRPTHRESHOLDSSB "rsrp_ThresholdSSB"
+#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR"
+#define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex"
+#define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing"
+#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig"
+#define GNB_CONFIG_STRING_MSG3TRANSFPREC "msg3_transformPrecoder"
#define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST "puschTimeDomainAllocationList"
#define GNB_CONFIG_STRING_MSG3DELTAPREABMLE "msg3_DeltaPreamble"
#define GNB_CONFIG_STRING_P0NOMINALWITHGRANT "p0_NominalWithGrant"
@@ -246,7 +247,7 @@
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:-1,TYPE_INT64,0/*17*/},\
{GNB_CONFIG_STRING_INITIALDLBWPK0_1,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->k0,defint64val:-1,TYPE_INT64,0/*18*/},\
{GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*19*/},\
-{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \
+{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \
{GNB_CONFIG_STRING_INITIALDLBWPK0_2,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->k0,defint64val:-1,TYPE_INT64,0/*21*/},\
{GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*22*/},\
{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength,defint64val:54,TYPE_INT64,0/*23*/},\
@@ -311,11 +312,12 @@
{GNB_CONFIG_STRING_RSRPTHRESHOLDSSB,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB,defint64val:19,TYPE_INT64,0/*82*/},\
{GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR,NULL,0,uptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present,defuintval:NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139,TYPE_UINT,0/*83*/},\
{GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139,defint64val:0,TYPE_INT64,0/*84*/},\
-{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \
-{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*86*/},\
-{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*87*/},\
-{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*88*/},\
-{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*89*/}, \
+{GNB_CONFIG_STRING_RESTRICTEDSETCONFIG,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \
+{GNB_CONFIG_STRING_MSG3TRANSFPREC,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder,defintval:1,TYPE_INT64,0/*86*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*87*/},\
+{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*88*/},\
+{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*89*/},\
+{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*90*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_2,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2,defint64val:-1,TYPE_INT64,0},\
@@ -325,7 +327,7 @@
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_4,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->k2,defint64val:-1,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*99*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*100*/}, \
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_5,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_5,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
@@ -335,7 +337,7 @@
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_6,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[6]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_7,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*109*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*110*/}, \
{GNB_CONFIG_STRING_INITIALULBWPK2_8,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
@@ -345,7 +347,7 @@
{GNB_CONFIG_STRING_INITIALULBWPK2_10,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*119*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*120*/}, \
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_12,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[12]->k2,defint64val:-1,TYPE_INT64,0},\
@@ -355,7 +357,7 @@
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_14,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->k2,defint64val:-1,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*129*/}, \
+{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*130*/}, \
{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPK2_15,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->k2,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_15,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\
@@ -365,7 +367,7 @@
{GNB_CONFIG_STRING_PUCCHGROUPHOPPING, NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_GroupHopping,defint64val:NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither,TYPE_INT64,0},\
{GNB_CONFIG_STRING_HOPPINGID, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId,defint64val:40,TYPE_INT64,0},\
{GNB_CONFIG_STRING_P0NOMINAL, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal,defint64val:1,TYPE_INT64,0},\
-{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*139*/}, \
+{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*140*/}, \
{GNB_CONFIG_STRING_SSBPOSITIONSINBURST,NULL,0,u64ptr:&ssb_bitmap,defintval:0xff,TYPE_UINT64,0}, \
{GNB_CONFIG_STRING_REFERENCESUBCARRIERSPACING,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing,defint64val:NR_SubcarrierSpacing_kHz30,TYPE_INT64,0},\
{GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity,defint64val:NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p5,TYPE_INT64,0},\
@@ -379,7 +381,7 @@
{GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,defint64val:-1,TYPE_INT64,0},\
{GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,i64ptr:&scc->ss_PBCH_BlockPower,defint64val:20,TYPE_INT64,0}, \
-{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0/*86*/}}
+{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0}}
diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c
index f419ec0790..0a6f906312 100644
--- a/openair2/GNB_APP/gnb_app.c
+++ b/openair2/GNB_APP/gnb_app.c
@@ -71,30 +71,30 @@ static void configure_nr_rrc(uint32_t gnb_id)
/*------------------------------------------------------------------------------*/
-/*
+
static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties)
{
uint32_t gnb_id;
- MessageDef *msg_p;
+ //MessageDef *msg_p;
uint32_t register_gnb_pending = 0;
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
{
- s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
+ //s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse
// note: there is an implicit relationship between the data structure and the message name
- msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
+ /*msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse
- RCconfig_NR_S1(msg_p, gnb_id);
+ RCconfig_NR_S1(msg_p, gnb_id);*/
if (gnb_id == 0) RCconfig_nr_gtpu();
- s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
- LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);
+ /*s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse
+ LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);*/
LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id));
- itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
+ //itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
register_gnb_pending++;
}
@@ -102,7 +102,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//,
return register_gnb_pending;
}
-*/
+
/*------------------------------------------------------------------------------*/
static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) {
@@ -175,7 +175,7 @@ void *gNB_app_task(void *args_p)
if (EPC_MODE_ENABLED) {
/* Try to register each gNB */
//registered_gnb = 0;
- //register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
+ __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p);
} else {
/* Start L2L1 task */
msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE);
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index e7fd2f3cf8..61aa10e47b 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -54,7 +54,8 @@
#include "common/config/config_userapi.h"
//#include "RRC_config_tools.h"
#include "gnb_paramdef.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
+
#include "NR_asn_constant.h"
#include "executables/thread-common.h"
#include "NR_SCS-SpecificCarrier.h"
@@ -254,10 +255,9 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = NULL;
}
- // fix libconfig (asn1c uses long)
- scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower-=((long)1<<32);
- *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant-=((long)1<<32);
- *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal-=((long)1<<32);
+ // default value for msg3 precoder is NULL (0 means enabled)
+ if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0)
+ scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NULL;
// fix DL and UL Allocation lists
@@ -714,10 +714,14 @@ int RCconfig_nr_gtpu(void ) {
if (address) {
MessageDef *message;
AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, GTPV1U_ENB_S1_REQ))!=NULL,"");
- IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
- LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
- GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
- itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
+ // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
+ // LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
+
+
+ IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
+ LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
+ GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
+ itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else
LOG_E(GTPU,"invalid address for S1U\n");
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 5801fabcfb..20b4c85dc6 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -41,6 +41,10 @@
#define NR_BCCH_BCH 5 // MIB
+#define CCCH_PAYLOAD_SIZE_MAX 128
+
+#define RAR_PAYLOAD_SIZE_MAX 128
+
// For both DL/UL-SCH
// Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
@@ -86,17 +90,93 @@ typedef struct {
uint8_t R:2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
+// BSR MAC CEs
+// TS 38.321 ch. 6.1.3.1
+// Short BSR for a specific logical channel group ID
+typedef struct {
+ uint8_t Buffer_size:5; // octet 1 LSB
+ uint8_t LcgID:3; // octet 1 MSB
+} __attribute__ ((__packed__)) NR_BSR_SHORT;
+
+typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
+
+// Long BSR for all logical channel group ID
+typedef struct {
+ uint8_t Buffer_size7:8;
+ uint8_t Buffer_size6:8;
+ uint8_t Buffer_size5:8;
+ uint8_t Buffer_size4:8;
+ uint8_t Buffer_size3:8;
+ uint8_t Buffer_size2:8;
+ uint8_t Buffer_size1:8;
+ uint8_t Buffer_size0:8;
+ uint8_t LcgID0:1;
+ uint8_t LcgID1:1;
+ uint8_t LcgID2:1;
+ uint8_t LcgID3:1;
+ uint8_t LcgID4:1;
+ uint8_t LcgID5:1;
+ uint8_t LcgID6:1;
+ uint8_t LcgID7:1;
+} __attribute__ ((__packed__)) NR_BSR_LONG;
+
+typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
+
// 38.321 ch. 6.1.3.4
typedef struct {
uint8_t TA_COMMAND:6; // octet 1 [5:0]
uint8_t TAGID:2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_CE_TA;
+// single Entry PHR MAC CE
+// TS 38.321 ch. 6.1.3.8
+typedef struct {
+ uint8_t PH:6;
+ uint8_t R1:2;
+ uint8_t PCMAX:6;
+ uint8_t R2:6;
+} __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE;
+
+//* RAR MAC subheader // TS 38.321 ch. 6.1.5, 6.2.2 *//
+// - E: The Extension field is a flag indicating if the MAC subPDU including this MAC subheader is the last MAC subPDU or not in the MAC PDU
+// - T: The Type field is a flag indicating whether the MAC subheader contains a Random Access Preamble ID or a Backoff Indicator (0, BI) (1, RAPID)
+// - R: Reserved bit, set to "0"
+// - BI: The Backoff Indicator field identifies the overload condition in the cell.
+// - RAPID: The Random Access Preamble IDentifier field identifies the transmitted Random Access Preamble
+
+/*!\brief RAR MAC subheader with RAPID */
+typedef struct {
+ uint8_t RAPID:6;
+ uint8_t T:1;
+ uint8_t E:1;
+} __attribute__ ((__packed__)) NR_RA_HEADER_RAPID;
+
+/*!\brief RAR MAC subheader with Backoff Indicator */
+typedef struct {
+ uint8_t BI:4;
+ uint8_t R:2;
+ uint8_t T:1;
+ uint8_t E:1;
+} __attribute__ ((__packed__)) NR_RA_HEADER_BI;
+
+// TS 38.321 ch. 6.2.3
+typedef struct {
+ uint8_t TA1:7; // octet 1 [6:0]
+ uint8_t R:1; // octet 1 [7]
+ uint8_t UL_GRANT_1:3; // octet 2 [2:0]
+ uint8_t TA2:5; // octet 2 [7:3]
+ uint8_t UL_GRANT_2:8; // octet 3 [7:0]
+ uint8_t UL_GRANT_3:8; // octet 4 [7:0]
+ uint8_t UL_GRANT_4:8; // octet 5 [7:0]
+ uint8_t TCRNTI_1:8; // octet 6 [7:0]
+ uint8_t TCRNTI_2:8; // octet 7 [7:0]
+} __attribute__ ((__packed__)) NR_MAC_RAR;
+
// 38.321 ch6.2.1, 38.331
#define DL_SCH_LCID_CCCH 0x00
#define DL_SCH_LCID_DCCH 0x01
#define DL_SCH_LCID_DCCH1 0x02
-#define DL_SCH_LCID_DTCH 0x03
+#define DL_SCH_LCID_DTCH 0x04
#define DL_SCH_LCID_RECOMMENDED_BITRATE 0x2F
#define DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT 0x30
#define DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT 0x31
@@ -118,8 +198,8 @@ typedef struct {
#define UL_SCH_LCID_CCCH 0x00
#define UL_SCH_LCID_SRB1 0x01
#define UL_SCH_LCID_SRB2 0x02
-#define UL_SCH_LCID_DTCH 0x03
-#define UL_SCH_LCID_SRB3 0x04
+#define UL_SCH_LCID_SRB3 0x03
+#define UL_SCH_LCID_DTCH 0x04
#define UL_SCH_LCID_CCCH_MSG3 0x21
#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35
#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index cfde40daad..9cf83c02ab 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -32,6 +32,1164 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
+uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419};
+uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case set Type A
+uint16_t NCS_restricted_TypeB_delta_f_RA_125[13] = {15,18,22,26,32,38,46,55,68,82,100,118,137}; // high-speed case set Type B
+
+// Table 6.3.3.1-6 (38.211) NCS for preamble formats with delta_f_RA = 5 KHz
+uint16_t NCS_unrestricted_delta_f_RA_5[16] = {0,13,26,33,38,41,49,55,64,76,93,119,139,209,279,419};
+uint16_t NCS_restricted_TypeA_delta_f_RA_5[16] = {36,57,72,81,89,94,103,112,121,132,137,152,173,195,216,237}; // high-speed case set Type A
+uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,85,97,109,122,137}; // high-speed case set Type B
+
+// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3}
+uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69};
+
+const char *prachfmt[]={"A1","A2","A3","B1","B2","B3","B4","C0","C2"};
+
+const uint16_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
+
+uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) {
+
+ if (format0 < 3) {
+ switch(restricted_set_config){
+ case 0:
+ return(NCS_unrestricted_delta_f_RA_125[index]);
+ case 1:
+ return(NCS_restricted_TypeA_delta_f_RA_125[index]);
+ case 2:
+ return(NCS_restricted_TypeB_delta_f_RA_125[index]);
+ default:
+ AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config);
+ }
+ }
+ else {
+ if (format0 == 3) {
+ switch(restricted_set_config){
+ case 0:
+ return(NCS_unrestricted_delta_f_RA_5[index]);
+ case 1:
+ return(NCS_restricted_TypeA_delta_f_RA_5[index]);
+ case 2:
+ return(NCS_restricted_TypeB_delta_f_RA_5[index]);
+ default:
+ AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config);
+ }
+ }
+ else
+ return(NCS_unrestricted_delta_f_RA_15[index]);
+ }
+}
+
+
+// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
+// the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent.
+// E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9.
+// E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6
+int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = {
+//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
+{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
+{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
+{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
+{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
+{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
+{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
+{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
+{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
+{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
+{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
+{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
+{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
+{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
+{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
+{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
+{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
+{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
+{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9
+{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
+{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5
+{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9
+{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1
+{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4
+{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7
+{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6
+{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7
+{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8
+{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7
+{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8
+{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9
+{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8
+{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9
+{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 8, 1, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 4, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 4, 1, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 4, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 2, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 2, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
+{0xa1, -1, 2, 0, 16, 0, 2, 6, 2}, // (subframe number) 4
+{0xa1, -1, 2, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
+{0xa1, -1, 1, 0, 16, 0, 1, 6, 2}, // (subframe number) 4
+{0xa1, -1, 1, 0, 66, 0, 1, 6, 2}, // (subframe number) 1,6
+{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9
+{0xa1, -1, 1, 0, 2, 0, 2, 6, 2}, // (subframe number) 1
+{0xa1, -1, 1, 0, 128, 0, 2, 6, 2}, // (subframe number) 7
+{0xa1, -1, 1, 0, 132, 0, 2, 6, 2}, // (subframe number) 2,7
+{0xa1, -1, 1, 0, 146, 0, 2, 6, 2}, // (subframe number) 1,4,7
+{0xa1, -1, 1, 0, 341, 0, 2, 6, 2}, // (subframe number) 0,2,4,6,8
+{0xa1, -1, 1, 0, 1023, 0, 2, 6, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa1, -1, 1, 0, 682, 0, 2, 6, 2}, // (subframe number) 1,3,5,7,9
+{0xa1, 0xb1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xa1, 0xb1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xa1, 0xb1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
+{0xa1, 0xb1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
+{0xa1, 0xb1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xa1, 0xb1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xa1, 0xb1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xa1, 0xb1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
+{0xa1, 0xb1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
+{0xa2, -1, 16, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 16, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 8, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 8, 1, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 4, 0, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 4, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, -1, 2, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
+{0xa2, -1, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, -1, 2, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
+{0xa2, -1, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
+{0xa2, -1, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
+{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
+{0xa2, -1, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
+{0xa2, -1, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
+{0xa2, -1, 1, 0, 132, 0, 2, 3, 4}, // (subframe number) 2,7
+{0xa2, -1, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
+{0xa2, -1, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
+{0xa2, -1, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa2, -1, 1, 0, 682, 0, 2, 3, 4}, // (subframe number) 1,3,5,7,9
+{0xa2, 0xb2, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9
+{0xa2, 0xb2, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4
+{0xa2, 0xb2, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4
+{0xa2, 0xb2, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6
+{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9
+{0xa2, 0xb2, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1
+{0xa2, 0xb2, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7
+{0xa2, 0xb2, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7
+{0xa2, 0xb2, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8
+{0xa2, 0xb2, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa3, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
+{0xa3, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xa3, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xa3, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
+{0xa3, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
+{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xa3, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xa3, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
+{0xa3, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
+{0xa3, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
+{0xa3, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xa3, -1, 1, 0, 682, 0, 2, 2, 6}, // (subframe number) 1,3,5,7,9
+{0xa3, 0xb3, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
+{0xa3, 0xb3, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xa3, 0xb3, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
+{0xa3, 0xb3, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
+{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xa3, 0xb3, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xa3, 0xb3, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xa3, 0xb3, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
+{0xa3, 0xb3, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
+{0xa3, 0xb3, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xb1, -1, 16, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 16, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 8, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 4, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xb1, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xb1, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xb1, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
+{0xb1, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
+{0xb1, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xb1, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xb1, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xb1, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
+{0xb1, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
+{0xb1, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
+{0xb1, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xb1, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
+{0xb4, -1, 16, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 16, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 8, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 8, 1, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 4, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 4, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 4, 1, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 2, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 2, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
+{0xb4, -1, 2, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 2, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
+{0xb4, -1, 1, 0, 2, 0, 2, 1, 12}, // (subframe number) 1
+{0xb4, -1, 1, 0, 16, 0, 2, 1, 12}, // (subframe number) 4
+{0xb4, -1, 1, 0, 128, 0, 2, 1, 12}, // (subframe number) 7
+{0xb4, -1, 1, 0, 66, 0, 2, 1, 12}, // (subframe number) 1,6
+{0xb4, -1, 1, 0, 132, 0, 2, 1, 12}, // (subframe number) 2,7
+{0xb4, -1, 1, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9
+{0xb4, -1, 1, 0, 146, 0, 2, 1, 12}, // (subframe number) 1,4,7
+{0xb4, -1, 1, 0, 341, 0, 2, 1, 12}, // (subframe number) 0,2,4,6,8
+{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xb4, -1, 1, 0, 682, 0, 2, 1, 12}, // (subframe number) 1,3,5,7,9
+{0xc0, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xc0, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xc0, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xc0, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xc0, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xc0, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4
+{0xc0, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xc0, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4
+{0xc0, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6
+{0xc0, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9
+{0xc0, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1
+{0xc0, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7
+{0xc0, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7
+{0xc0, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7
+{0xc0, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8
+{0xc0, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xc0, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9
+{0xc2, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9
+{0xc2, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xc2, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4
+{0xc2, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xc2, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4
+{0xc2, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6
+{0xc2, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9
+{0xc2, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1
+{0xc2, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7
+{0xc2, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7
+{0xc2, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7
+{0xc2, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8
+{0xc2, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9
+{0xc2, -1, 1, 0, 682, 0, 2, 2, 6} // (subframe number) 1,3,5,7,9
+};
+// Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum
+int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = {
+//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
+{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
+{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
+{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
+{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
+{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
+{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
+{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
+{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
+{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
+{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
+{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
+{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
+{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
+{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
+{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
+{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
+{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9)
+{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
+{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
+{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7)
+{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
+{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
+{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6)
+{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
+{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6)
+{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6)
+{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4)
+{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9)
+{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8)
+{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7)
+{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6)
+{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5)
+{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4)
+{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3)
+{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2)
+{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6)
+{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6)
+{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9)
+{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8)
+{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7)
+{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9)
+{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9)
+{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9)
+{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9)
+{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9)
+{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9)
+{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9)
+{0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
+{0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9)
+{0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
+{0xa1, -1, 2, 1, 512, 0, 1, 6, 2}, // (subrame number 9)
+{0xa1, -1, 2, 1, 528, 7, 1, 3, 2}, // (subrame number 4,9)
+{0xa1, -1, 2, 1, 640, 7, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, -1, 2, 1, 640, 0, 1, 6, 2}, // (subrame number 7,9)
+{0xa1, -1, 2, 1, 768, 0, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, -1, 2, 1, 528, 0, 2, 6, 2}, // (subrame number 4,9)
+{0xa1, -1, 2, 1, 924, 0, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
+{0xa1, -1, 1, 0, 512, 0, 2, 6, 2}, // (subrame number 9)
+{0xa1, -1, 1, 0, 512, 7, 1, 3, 2}, // (subrame number 9)
+{0xa1, -1, 1, 0, 512, 0, 1, 6, 2}, // (subrame number 9)
+{0xa1, -1, 1, 0, 768, 0, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subrame number 4,9)
+{0xa1, -1, 1, 0, 640, 7, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, -1, 1, 0, 792, 0, 1, 6, 2}, // (subrame number 3,4,8,9)
+{0xa1, -1, 1, 0, 792, 0, 2, 6, 2}, // (subrame number 3,4,8,9)
+{0xa1, -1, 1, 0, 682, 0, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xa1, -1, 1, 0, 1023, 7, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa2, -1, 16, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, -1, 8, 1, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, -1, 4, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, -1, 2, 1, 640, 0, 1, 3, 4}, // (subrame number 7,9)
+{0xa2, -1, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, -1, 2, 1, 640, 9, 1, 1, 4}, // (subrame number 7,9)
+{0xa2, -1, 2, 1, 528, 9, 1, 1, 4}, // (subrame number 4,9)
+{0xa2, -1, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
+{0xa2, -1, 16, 1, 924, 0, 1, 3, 4}, // (subrame number 2,3,4,7,8,9)
+{0xa2, -1, 1, 0, 4, 0, 1, 3, 4}, // (subrame number 2)
+{0xa2, -1, 1, 0, 128, 0, 1, 3, 4}, // (subrame number 7)
+{0xa2, -1, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 512, 9, 1, 1, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, -1, 1, 0, 132, 0, 1, 3, 4}, // (subrame number 2,7)
+{0xa2, -1, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
+{0xa2, -1, 1, 0, 640, 9, 1, 1, 4}, // (subrame number 7,9)
+{0xa2, -1, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, -1, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, -1, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
+{0xa2, -1, 1, 0, 1023, 9, 1, 1, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa3, -1, 16, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, -1, 8, 1, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, -1, 4, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, -1, 2, 1, 528, 7, 1, 1, 6}, // (subrame number 4,9)
+{0xa3, -1, 2, 1, 640, 7, 1, 1, 6}, // (subrame number 7,9)
+{0xa3, -1, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, -1, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
+{0xa3, -1, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, -1, 2, 1, 924, 0, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
+{0xa3, -1, 1, 0, 4, 0, 1, 2, 6}, // (subrame number 2)
+{0xa3, -1, 1, 0, 128, 0, 1, 2, 6}, // (subrame number 7)
+{0xa3, -1, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 512, 7, 1, 1, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, -1, 1, 0, 132, 0, 1, 2, 6}, // (subrame number 2,7)
+{0xa3, -1, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
+{0xa3, -1, 1, 0, 640, 7, 1, 1, 6}, // (subrame number 7,9)
+{0xa3, -1, 1, 0, 792, 0, 1, 2, 6}, // (subrame number 3,4,8,9)
+{0xa3, -1, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
+{0xa3, -1, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
+{0xa3, -1, 1, 0, 1023, 7, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xb1, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xb1, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xb1, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
+{0xb1, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
+{0xb1, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
+{0xb1, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xb1, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
+{0xb1, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xb1, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xb1, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
+{0xb1, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xb1, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xb4, -1, 16, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
+{0xb4, -1, 8, 1, 512, 0, 2, 1, 12}, // (subrame number 9)
+{0xb4, -1, 4, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 2, 1, 512, 0, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 2, 1, 512, 2, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 2, 1, 640, 2, 1, 1, 12}, // (subrame number 7,9)
+{0xb4, -1, 2, 1, 528, 2, 1, 1, 12}, // (subrame number 4,9)
+{0xb4, -1, 2, 1, 528, 0, 2, 1, 12}, // (subrame number 4,9)
+{0xb4, -1, 2, 1, 768, 0, 2, 1, 12}, // (subrame number 8,9)
+{0xb4, -1, 2, 1, 924, 0, 1, 1, 12}, // (subrame number 2,3,4,7,8,9)
+{0xb4, -1, 1, 0, 2, 0, 1, 1, 12}, // (subrame number 1)
+{0xb4, -1, 1, 0, 4, 0, 1, 1, 12}, // (subrame number 2)
+{0xb4, -1, 1, 0, 16, 0, 1, 1, 12}, // (subrame number 4)
+{0xb4, -1, 1, 0, 128, 0, 1, 1, 12}, // (subrame number 7)
+{0xb4, -1, 1, 0, 512, 0, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 1, 0, 512, 2, 1, 1, 12}, // (subrame number 9)
+{0xb4, -1, 1, 0, 512, 0, 2, 1, 12}, // (subrame number 9)
+{0xb4, -1, 1, 0, 528, 2, 1, 1, 12}, // (subrame number 4,9)
+{0xb4, -1, 1, 0, 640, 2, 1, 1, 12}, // (subrame number 7,9)
+{0xb4, -1, 1, 0, 768, 0, 2, 1, 12}, // (subrame number 8,9)
+{0xb4, -1, 1, 0, 792, 2, 1, 1, 12}, // (subrame number 3,4,8,9)
+{0xb4, -1, 1, 0, 682, 2, 1, 1, 12}, // (subrame number 1,3,5,7,9)
+{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xb4, -1, 1, 0, 1023, 2, 1, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xc0, -1, 16, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xc0, -1, 8, 1, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xc0, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xc0, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xc0, -1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xc0, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
+{0xc0, -1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xc0, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
+{0xc0, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
+{0xc0, -1, 2, 1, 924, 2, 1, 6, 2}, // (subrame number 2,3,4,7,8,9)
+{0xc0, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xc0, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
+{0xc0, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xc0, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xc0, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
+{0xc0, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xc0, -1, 1, 0, 792, 2, 1, 6, 2}, // (subrame number 3,4,8,9)
+{0xc0, -1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
+{0xc0, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xc0, -1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xc2, -1, 16, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
+{0xc2, -1, 8, 1, 512, 2, 2, 2, 6}, // (subrame number 9)
+{0xc2, -1, 4, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xc2, -1, 2, 1, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xc2, -1, 2, 1, 768, 2, 2, 2, 6}, // (subrame number 8,9)
+{0xc2, -1, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
+{0xc2, -1, 2, 1, 640, 8, 1, 1, 6}, // (subrame number 7,9)
+{0xc2, -1, 2, 1, 528, 8, 1, 1, 6}, // (subrame number 4,9)
+{0xc2, -1, 2, 1, 528, 2, 2, 2, 6}, // (subrame number 4,9)
+{0xc2, -1, 2, 1, 924, 2, 1, 2, 6}, // (subrame number 2,3,4,7,8,9)
+{0xc2, -1, 8, 1, 512, 8, 2, 1, 6}, // (subrame number 9)
+{0xc2, -1, 4, 1, 512, 8, 1, 1, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 512, 2, 2, 2, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 512, 8, 1, 1, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xc2, -1, 1, 0, 768, 2, 2, 2, 6}, // (subrame number 8,9)
+{0xc2, -1, 1, 0, 528, 2, 1, 2, 6}, // (subrame number 4,9)
+{0xc2, -1, 1, 0, 640, 8, 1, 1, 6}, // (subrame number 7,9)
+{0xc2, -1, 1, 0, 792, 2, 1, 2, 6}, // (subrame number 3,4,8,9)
+{0xc2, -1, 1, 0, 792, 2, 2, 2, 6}, // (subrame number 3,4,8,9)
+{0xc2, -1, 1, 0, 682, 2, 1, 2, 6}, // (subrame number 1,3,5,7,9)
+{0xc2, -1, 1, 0, 1023, 8, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa1, 0xb1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xa1, 0xb1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9)
+{0xa1, 0xb1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, 0xb1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9)
+{0xa1, 0xb1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9)
+{0xa1, 0xb1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, 0xb1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9)
+{0xa1, 0xb1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9)
+{0xa1, 0xb1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9)
+{0xa1, 0xb1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9)
+{0xa1, 0xb1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9)
+{0xa1, 0xb1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9)
+{0xa1, 0xb1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9)
+{0xa1, 0xb1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9)
+{0xa1, 0xb1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa2, 0xb2, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, 0xb2, 2, 1, 528, 6, 1, 2, 4}, // (subrame number 4,9)
+{0xa2, 0xb2, 2, 1, 640, 6, 1, 2, 4}, // (subrame number 7,9)
+{0xa2, 0xb2, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9)
+{0xa2, 0xb2, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, 0xb2, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9)
+{0xa2, 0xb2, 1, 0, 512, 6, 1, 2, 4}, // (subrame number 9)
+{0xa2, 0xb2, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9)
+{0xa2, 0xb2, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9)
+{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9)
+{0xa2, 0xb2, 1, 0, 640, 6, 1, 2, 4}, // (subrame number 7,9)
+{0xa2, 0xb2, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, 0xb2, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9)
+{0xa2, 0xb2, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9)
+{0xa2, 0xb2, 1, 0, 1023, 6, 1, 2, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9)
+{0xa3, 0xb3, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 2, 1, 528, 2, 1, 2, 6}, // (subrame number 4,9)
+{0xa3, 0xb3, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, 0xb3, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, 0xb3, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9)
+{0xa3, 0xb3, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, 0xb3, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9)
+{0xa3, 0xb3, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9)
+{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9)
+{0xa3, 0xb3, 1, 0, 640, 2, 1, 2, 6}, // (subrame number 7,9)
+{0xa3, 0xb3, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9)
+{0xa3, 0xb3, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9)
+{0xa3, 0xb3, 1, 0, 1023, 2, 1, 2, 6} // (subrame number 0,1,2,3,4,5,6,7,8,9)
+};
+// Table 6.3.3.2-4: Random access configurations for FR2 and unpaired spectrum
+int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = {
+//format, format, x, y, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration
+{0xa1, -1, 16, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 16, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 8, 1, 2, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xa1, -1, 8, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 8, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 4, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 4, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 4, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 2, 1, -1, 551911719040, 0, 2, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xa1, -1, 2, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 2, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 2, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 549756338176, 7, 1, 3, 2}, // (subframe number :19,39)
+{0xa1, -1, 1, 0, -1, 168, 0, 1, 6, 2}, // (subframe number :3,5,7)
+{0xa1, -1, 1, 0, -1, 567489331200, 7, 1, 3, 2}, // (subframe number :24,29,34,39)
+{0xa1, -1, 1, 0, -1, 550293209600, 7, 2, 3, 2}, // (subframe number :9,19,29,39)
+{0xa1, -1, 1, 0, -1, 687195422720, 0, 1, 6, 2}, // (subframe number :17,19,37,39)
+{0xa1, -1, 1, 0, -1, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xa1, -1, 1, 0, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 1, 0, -1, 567489872400, 7, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, -1, 1, 0, -1, 10920, 7, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
+{0xa1, -1, 1, 0, -1, 586405642240, 7, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 551911719040, 0, 1, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xa1, -1, 1, 0, -1, 586405642240, 0, 1, 6, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 965830828032, 7, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xa1, -1, 1, 0, -1, 586406201480, 7, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, -1, 1, 0, -1, 733007751850, 0, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xa1, -1, 1, 0, -1, 1099511627775, 7, 1, 3, 2}, // (subframe number :0,1,2,…,39)
+{0xa2, -1, 16, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 16, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 8, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 8, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 8, 1, 2, 550293209600, 0, 2, 3, 4}, // (subframe number :9,19,29,39)
+{0xa2, -1, 4, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 4, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 4, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 2, 1, -1, 551911719040, 0, 2, 3, 4}, // (subframe number :7,15,23,31,39)
+{0xa2, -1, 2, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 2, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 2, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 549756338176, 5, 1, 2, 4}, // (subframe number :19,39)
+{0xa2, -1, 1, 0, -1, 168, 0, 1, 3, 4}, // (subframe number :3,5,7)
+{0xa2, -1, 1, 0, -1, 567489331200, 5, 1, 2, 4}, // (subframe number :24,29,34,39)
+{0xa2, -1, 1, 0, -1, 550293209600, 5, 2, 2, 4}, // (subframe number :9,19,29,39)
+{0xa2, -1, 1, 0, -1, 687195422720, 0, 1, 3, 4}, // (subframe number :17,19,37,39)
+{0xa2, -1, 1, 0, -1, 550293209600, 0, 2, 3, 4}, // (subframe number :9, 19, 29, 39)
+{0xa2, -1, 1, 0, -1, 551911719040, 0, 1, 3, 4}, // (subframe number :7,15,23,31,39)
+{0xa2, -1, 1, 0, -1, 586405642240, 5, 1, 2, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 586405642240, 0, 1, 3, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 10920, 5, 1, 2, 4}, // (subframe number :3,5,7,9,11,13)
+{0xa2, -1, 1, 0, -1, 10920, 0, 1, 3, 4}, // (subframe number :3,5,7,9,11,13)
+{0xa2, -1, 1, 0, -1, 567489872400, 5, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 1, 0, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, -1, 1, 0, -1, 965830828032, 5, 2, 2, 4}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xa2, -1, 1, 0, -1, 586406201480, 5, 1, 2, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, -1, 1, 0, -1, 733007751850, 0, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
+{0xa2, -1, 1, 0, -1, 1099511627775, 5, 1, 2, 4}, // (subframe number :0,1,2,…,39)
+{0xa3, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 549756338176, 7, 1, 1, 6}, // (subframe number :19,39)
+{0xa3, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
+{0xa3, -1, 1, 0, -1, 10752, 2, 1, 2, 6}, // (subframe number :9,11,13)
+{0xa3, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
+{0xa3, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
+{0xa3, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
+{0xa3, -1, 1, 0, -1, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, -1, 1, 0, -1, 551911719040, 0, 1, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xa3, -1, 1, 0, -1, 586405642240, 7, 1, 1, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 10920, 0, 1, 2, 6}, // (subframe number :3,5,7,9,11,13)
+{0xa3, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
+{0xa3, -1, 1, 0, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 1, 0, -1, 567489872400, 7, 1, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xa3, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
+{0xa3, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
+{0xb1, -1, 16, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 8, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 8, 1, 2, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xb1, -1, 4, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 2, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 2, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
+{0xb1, -1, 1, 0, -1, 168, 2, 1, 6, 2}, // (subframe number :3,5,7)
+{0xb1, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
+{0xb1, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
+{0xb1, -1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
+{0xb1, -1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xb1, -1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xb1, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
+{0xb1, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb1, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xb1, -1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb1, -1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xb1, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
+{0xb4, -1, 16, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 16, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 8, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 8, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 8, 1, 2, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
+{0xb4, -1, 4, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 4, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 4, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 2, 1, -1, 551911719040, 2, 2, 1, 12}, // (subframe number :7,15,23,31,39)
+{0xb4, -1, 2, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 2, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 2, 1, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 549756338176, 2, 2, 1, 12}, // (subframe number :19, 39)
+{0xb4, -1, 1, 0, -1, 687195422720, 0, 1, 1, 12}, // (subframe number :17, 19, 37, 39)
+{0xb4, -1, 1, 0, -1, 567489331200, 2, 1, 1, 12}, // (subframe number :24,29,34,39)
+{0xb4, -1, 1, 0, -1, 550293209600, 2, 2, 1, 12}, // (subframe number :9,19,29,39)
+{0xb4, -1, 1, 0, -1, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39)
+{0xb4, -1, 1, 0, -1, 551911719040, 0, 1, 1, 12}, // (subframe number :7,15,23,31,39)
+{0xb4, -1, 1, 0, -1, 551911719040, 0, 2, 1, 12}, // (subframe number :7,15,23,31,39)
+{0xb4, -1, 1, 0, -1, 586405642240, 0, 1, 1, 12}, // (subframe number :23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 586405642240, 2, 2, 1, 12}, // (subframe number :23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 698880, 0, 1, 1, 12}, // (subframe number :9,11,13,15,17,19)
+{0xb4, -1, 1, 0, -1, 10920, 2, 1, 1, 12}, // (subframe number :3,5,7,9,11,13)
+{0xb4, -1, 1, 0, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 1, 0, -1, 567489872400, 2, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xb4, -1, 1, 0, -1, 965830828032, 2, 2, 1, 12}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xb4, -1, 1, 0, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 586406201480, 2, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xb4, -1, 1, 0, -1, 44739240, 2, 1, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
+{0xb4, -1, 1, 0, -1, 44739240, 0, 2, 1, 12}, // (subframe number :3, 5, 7, …, 23,25)
+{0xb4, -1, 1, 0, -1, 733007751850, 0, 1, 1, 12}, // (subframe number :1,3,5,7,…,37,39)
+{0xb4, -1, 1, 0, -1, 1099511627775, 2, 1, 1, 12}, // (subframe number :0, 1, 2,…, 39)
+{0xc0, -1, 16, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 16, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 8, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 8, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 8, 1, 2, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
+{0xc0, -1, 4, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 4, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 4, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 2, 1, -1, 551911719040, 0, 2, 7, 2}, // (subframe number :7,15,23,31,39)
+{0xc0, -1, 2, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 2, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 2, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
+{0xc0, -1, 1, 0, -1, 168, 0, 1, 7, 2}, // (subframe number :3,5,7)
+{0xc0, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39)
+{0xc0, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39)
+{0xc0, -1, 1, 0, -1, 687195422720, 0, 1, 7, 2}, // (subframe number :17,19,37,39)
+{0xc0, -1, 1, 0, -1, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39)
+{0xc0, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 551911719040, 0, 1, 7, 2}, // (subframe number :7,15,23,31,39)
+{0xc0, -1, 1, 0, -1, 586405642240, 0, 1, 7, 2}, // (subframe number :23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13)
+{0xc0, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 1, 0, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc0, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xc0, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc0, -1, 1, 0, -1, 733007751850, 0, 1, 7, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xc0, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39)
+{0xc2, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xc2, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 2, 1, -1, 551911719040, 2, 2, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xc2, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
+{0xc2, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7)
+{0xc2, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39)
+{0xc2, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39)
+{0xc2, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39)
+{0xc2, -1, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xc2, -1, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xc2, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13)
+{0xc2, -1, 1, 0, -1, 586405642240, 7, 2, 1, 6}, // (subframe number :23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 567489872400, 7, 2, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xc2, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39)
+{0xc2, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xc2, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39)
+{0xc2, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39)
+{0xa1, 0xb1, 16, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 16, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 8, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 8, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 4, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 4, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 2, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39)
+{0xa1, 0xb1, 1, 0, -1, 550293209600, 8, 1, 3, 2}, // (subframe number :9,19,29,39)
+{0xa1, 0xb1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39)
+{0xa1, 0xb1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39)
+{0xa1, 0xb1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, 0xb1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39)
+{0xa1, 0xb1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39)
+{0xa1, 0xb1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa1, 0xb1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa1, 0xb1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39)
+{0xa2, 0xb2, 16, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 16, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 8, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 8, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 4, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 4, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 2, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 1, 0, -1, 549756338176, 6, 1, 2, 4}, // (subframe number :19,39)
+{0xa2, 0xb2, 1, 0, -1, 550293209600, 6, 1, 2, 4}, // (subframe number :9,19,29,39)
+{0xa2, 0xb2, 1, 0, -1, 687195422720, 2, 1, 3, 4}, // (subframe number :17,19,37,39)
+{0xa2, 0xb2, 1, 0, -1, 550293209600, 2, 2, 3, 4}, // (subframe number :9,19,29,39)
+{0xa2, 0xb2, 1, 0, -1, 586405642240, 6, 1, 2, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, 0xb2, 1, 0, -1, 551911719040, 2, 1, 3, 4}, // (subframe number :7,15,23,31,39)
+{0xa2, 0xb2, 1, 0, -1, 586405642240, 2, 1, 3, 4}, // (subframe number :23,27,31,35,39)
+{0xa2, 0xb2, 1, 0, -1, 567489872400, 6, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 1, 0, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa2, 0xb2, 1, 0, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa2, 0xb2, 1, 0, -1, 733007751850, 2, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39)
+{0xa3, 0xb3, 16, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 16, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 8, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 8, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 4, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 4, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 2, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39)
+{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 1, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, 0xb3, 1, 0, -1, 687195422720, 2, 1, 2, 6}, // (subframe number :17,19,37,39)
+{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39)
+{0xa3, 0xb3, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39)
+{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 1, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 2, 2, 6}, // (subframe number :23,27,31,35,39)
+{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39)
+{0xa3, 0xb3, 1, 0, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39)
+{0xa3, 0xb3, 1, 0, -1, 733007751850, 2, 1, 2, 6} // (subframe number :1,3,5,7,…,37,39)
+};
+
+
+int get_format0(uint8_t index,
+ uint8_t unpaired){
+
+ uint16_t format;
+ if (unpaired)
+ format = table_6_3_3_2_3_prachConfig_Index[index][0];
+ else
+ format = table_6_3_3_2_2_prachConfig_Index[index][0];
+
+ return format;
+}
+
+void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
+ uint16_t *slot_period,
+ uint16_t *offset) {
+
+ switch(ss->monitoringSlotPeriodicityAndOffset->present) {
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1:
+ *slot_period = 1;
+ *offset = 0;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2:
+ *slot_period = 2;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4:
+ *slot_period = 4;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5:
+ *slot_period = 5;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8:
+ *slot_period = 8;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10:
+ *slot_period = 10;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16:
+ *slot_period = 16;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20:
+ *slot_period = 20;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40:
+ *slot_period = 40;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80:
+ *slot_period = 80;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160:
+ *slot_period = 160;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320:
+ *slot_period = 320;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640:
+ *slot_period = 640;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280:
+ *slot_period = 1280;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280;
+ break;
+ case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560:
+ *slot_period = 2560;
+ *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560;
+ break;
+ default:
+ AssertFatal(1==0,"Invalid monitoring slot periodicity and offset value\n");
+ break;
+ }
+}
+
+int get_nr_prach_info_from_index(uint8_t index,
+ int frame,
+ int slot,
+ uint32_t pointa,
+ uint8_t mu,
+ uint8_t unpaired,
+ uint16_t *format,
+ uint8_t *start_symbol,
+ uint8_t *N_t_slot,
+ uint8_t *N_dur) {
+
+ int x,y;
+ int64_t s_map;
+ uint8_t format2 = 0xff;
+
+ if (pointa > 2016666) { //FR2
+ int y2;
+ uint8_t slot_60khz;
+ x = table_6_3_3_2_4_prachConfig_Index[index][2];
+ y = table_6_3_3_2_4_prachConfig_Index[index][3];
+ y2 = table_6_3_3_2_4_prachConfig_Index[index][4];
+ // checking n_sfn mod x = y
+ if ( (frame%x)==y || (frame%x)==y2 ) {
+ slot_60khz = slot >> (mu-2); // in table slots are numbered wrt 60kHz
+ s_map = table_6_3_3_2_4_prachConfig_Index[index][5];
+ if ( (s_map>>slot_60khz)&0x01 ) {
+ if (mu == 3) {
+ if ( (table_6_3_3_2_4_prachConfig_Index[index][7] == 1) && (slot%2 == 0) )
+ return 0; // no prach in even slots @ 120kHz for 1 prach per 60khz slot
+ }
+ if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
+ *start_symbol = table_6_3_3_2_4_prachConfig_Index[index][6];
+ *N_t_slot = table_6_3_3_2_4_prachConfig_Index[index][8];
+ *N_dur = table_6_3_3_2_4_prachConfig_Index[index][9];
+ if (table_6_3_3_2_4_prachConfig_Index[index][1] != -1)
+ format2 = (uint8_t) table_6_3_3_2_4_prachConfig_Index[index][1];
+ *format = ((uint8_t) table_6_3_3_2_4_prachConfig_Index[index][0]) | (format2<<8);
+ LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
+ slot,
+ index,
+ pointa,
+ mu,
+ unpaired,
+ *start_symbol,
+ *N_t_slot,
+ *N_dur);
+ }
+ return 1;
+ }
+ else
+ return 0; // no prach in current slot
+ }
+ else
+ return 0; // no prach in current frame
+ }
+ else {
+ uint8_t subframe;
+ if (unpaired) {
+ x = table_6_3_3_2_3_prachConfig_Index[index][2];
+ y = table_6_3_3_2_3_prachConfig_Index[index][3];
+ if ( (frame%x)==y ) {
+ subframe = slot >> mu;
+ s_map = table_6_3_3_2_3_prachConfig_Index[index][4];
+ if ( (s_map>>subframe)&0x01 ) {
+ if (mu == 1) {
+ if ( (table_6_3_3_2_3_prachConfig_Index[index][6] == 1) && (slot%2 == 0) )
+ return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
+ }
+ if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
+ *start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5];
+ *N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7];
+ *N_dur = table_6_3_3_2_3_prachConfig_Index[index][8];
+ if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1)
+ format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1];
+ *format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8);
+ LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
+ slot,
+ index,
+ pointa,
+ mu,
+ unpaired,
+ *start_symbol,
+ *N_t_slot,
+ *N_dur);
+ }
+ return 1;
+ }
+ else
+ return 0; // no prach in current slot
+ }
+ else
+ return 0; // no prach in current frame
+ }
+ else { // FDD
+ x = table_6_3_3_2_2_prachConfig_Index[index][2];
+ y = table_6_3_3_2_2_prachConfig_Index[index][3];
+ if ( (frame%x)==y ) {
+ subframe = slot >> mu;
+ s_map = table_6_3_3_2_2_prachConfig_Index[index][4];
+ if ( (s_map>>subframe)&0x01 ) {
+ if (mu == 1) {
+ if ( (table_6_3_3_2_2_prachConfig_Index[index][6] == 1) && (slot%2 == 0) )
+ return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
+ }
+ if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
+ *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
+ *N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7];
+ *N_dur = table_6_3_3_2_2_prachConfig_Index[index][8];
+ if (table_6_3_3_2_2_prachConfig_Index[index][1] != -1)
+ format2 = (uint8_t) table_6_3_3_2_2_prachConfig_Index[index][1];
+ *format = ((uint8_t) table_6_3_3_2_2_prachConfig_Index[index][0]) | (format2<<8);
+ LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame,
+ slot,
+ index,
+ pointa,
+ mu,
+ unpaired,
+ *start_symbol,
+ *N_t_slot,
+ *N_dur);
+ }
+ return 1;
+ }
+ else
+ return 0; // no prach in current slot
+ }
+ else
+ return 0; // no prach in current frame
+ }
+ }
+}
+
+//Table 6.3.3.1-3: Mapping from logical index i to sequence number u for preamble formats with L_RA = 839
+uint16_t table_63313[838] = {
+129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84 , 755, 105, 734, 93 , 746, 70 , 769, 60 , 779,
+2 , 837, 1 , 838, 56 , 783, 112, 727, 148, 691, 80 , 759, 42 , 797, 40 , 799, 35 , 804, 73 , 766,
+146, 693, 31 , 808, 28 , 811, 30 , 809, 27 , 812, 29 , 810, 24 , 815, 48 , 791, 68 , 771, 74 , 765,
+178, 661, 136, 703, 86 , 753, 78 , 761, 43 , 796, 39 , 800, 20 , 819, 21 , 818, 95 , 744, 202, 637,
+190, 649, 181, 658, 137, 702, 125, 714, 151, 688, 217, 622, 128, 711, 142, 697, 122, 717, 203, 636,
+118, 721, 110, 729, 89 , 750, 103, 736, 61 , 778, 55 , 784, 15 , 824, 14 , 825, 12 , 827, 23 , 816,
+34 , 805, 37 , 802, 46 , 793, 207, 632, 179, 660, 145, 694, 130, 709, 223, 616, 228, 611, 227, 612,
+132, 707, 133, 706, 143, 696, 135, 704, 161, 678, 201, 638, 173, 666, 106, 733, 83 , 756, 91 , 748,
+66 , 773, 53 , 786, 10 , 829, 9 , 830, 7 , 832, 8 , 831, 16 , 823, 47 , 792, 64 , 775, 57 , 782,
+104, 735, 101, 738, 108, 731, 208, 631, 184, 655, 197, 642, 191, 648, 121, 718, 141, 698, 149, 690,
+216, 623, 218, 621, 152, 687, 144, 695, 134, 705, 138, 701, 199, 640, 162, 677, 176, 663, 119, 720,
+158, 681, 164, 675, 174, 665, 171, 668, 170, 669, 87 , 752, 169, 670, 88 , 751, 107, 732, 81 , 758,
+82 , 757, 100, 739, 98 , 741, 71 , 768, 59 , 780, 65 , 774, 50 , 789, 49 , 790, 26 , 813, 17 , 822,
+13 , 826, 6 , 833, 5 , 834, 33 , 806, 51 , 788, 75 , 764, 99 , 740, 96 , 743, 97 , 742, 166, 673,
+172, 667, 175, 664, 187, 652, 163, 676, 185, 654, 200, 639, 114, 725, 189, 650, 115, 724, 194, 645,
+195, 644, 192, 647, 182, 657, 157, 682, 156, 683, 211, 628, 154, 685, 123, 716, 139, 700, 212, 627,
+153, 686, 213, 626, 215, 624, 150, 689, 225, 614, 224, 615, 221, 618, 220, 619, 127, 712, 147, 692,
+124, 715, 193, 646, 205, 634, 206, 633, 116, 723, 160, 679, 186, 653, 167, 672, 79 , 760, 85 , 754,
+77 , 762, 92 , 747, 58 , 781, 62 , 777, 69 , 770, 54 , 785, 36 , 803, 32 , 807, 25 , 814, 18 , 821,
+11 , 828, 4 , 835, 3 , 836, 19 , 820, 22 , 817, 41 , 798, 38 , 801, 44 , 795, 52 , 787, 45 , 794,
+63 , 776, 67 , 772, 72 , 767, 76 , 763, 94 , 745, 102, 737, 90 , 749, 109, 730, 165, 674, 111, 728,
+209, 630, 204, 635, 117, 722, 188, 651, 159, 680, 198, 641, 113, 726, 183, 656, 180, 659, 177, 662,
+196, 643, 155, 684, 214, 625, 126, 713, 131, 708, 219, 620, 222, 617, 226, 613, 230, 609, 232, 607,
+262, 577, 252, 587, 418, 421, 416, 423, 413, 426, 411, 428, 376, 463, 395, 444, 283, 556, 285, 554,
+379, 460, 390, 449, 363, 476, 384, 455, 388, 451, 386, 453, 361, 478, 387, 452, 360, 479, 310, 529,
+354, 485, 328, 511, 315, 524, 337, 502, 349, 490, 335, 504, 324, 515, 323, 516, 320, 519, 334, 505,
+359, 480, 295, 544, 385, 454, 292, 547, 291, 548, 381, 458, 399, 440, 380, 459, 397, 442, 369, 470,
+377, 462, 410, 429, 407, 432, 281, 558, 414, 425, 247, 592, 277, 562, 271, 568, 272, 567, 264, 575,
+259, 580, 237, 602, 239, 600, 244, 595, 243, 596, 275, 564, 278, 561, 250, 589, 246, 593, 417, 422,
+248, 591, 394, 445, 393, 446, 370, 469, 365, 474, 300, 539, 299, 540, 364, 475, 362, 477, 298, 541,
+312, 527, 313, 526, 314, 525, 353, 486, 352, 487, 343, 496, 327, 512, 350, 489, 326, 513, 319, 520,
+332, 507, 333, 506, 348, 491, 347, 492, 322, 517, 330, 509, 338, 501, 341, 498, 340, 499, 342, 497,
+301, 538, 366, 473, 401, 438, 371, 468, 408, 431, 375, 464, 249, 590, 269, 570, 238, 601, 234, 605,
+257, 582, 273, 566, 255, 584, 254, 585, 245, 594, 251, 588, 412, 427, 372, 467, 282, 557, 403, 436,
+396, 443, 392, 447, 391, 448, 382, 457, 389, 450, 294, 545, 297, 542, 311, 528, 344, 495, 345, 494,
+318, 521, 331, 508, 325, 514, 321, 518, 346, 493, 339, 500, 351, 488, 306, 533, 289, 550, 400, 439,
+378, 461, 374, 465, 415, 424, 270, 569, 241, 598, 231, 608, 260, 579, 268, 571, 276, 563, 409, 430,
+398, 441, 290, 549, 304, 535, 308, 531, 358, 481, 316, 523, 293, 546, 288, 551, 284, 555, 368, 471,
+253, 586, 256, 583, 263, 576, 242, 597, 274, 565, 402, 437, 383, 456, 357, 482, 329, 510, 317, 522,
+307, 532, 286, 553, 287, 552, 266, 573, 261, 578, 236, 603, 303, 536, 356, 483, 355, 484, 405, 434,
+404, 435, 406, 433, 235, 604, 267, 572, 302, 537, 309, 530, 265, 574, 233, 606, 367, 472, 296, 543,
+336, 503, 305, 534, 373, 466, 280, 559, 279, 560, 419, 420, 240, 599, 258, 581, 229, 610
+};
+
+uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
+ uint8_t nb_preambles,
+ uint8_t unpaired) {
+
+ uint8_t config_index = rach_config->rach_ConfigGeneric.prach_ConfigurationIndex;
+ uint8_t ncs_index = rach_config->rach_ConfigGeneric.zeroCorrelationZoneConfig;
+ uint16_t format0 = get_format0(config_index, unpaired);
+ uint16_t NCS = get_NCS(ncs_index, format0, rach_config->restrictedSetConfig);
+ uint16_t L_ra = (rach_config->prach_RootSequenceIndex.present) ? 139 : 839;
+ uint16_t r,u,index,q,d_u,n_shift_ra,n_shift_ra_bar,d_start;
+ uint32_t w;
+ uint8_t found_preambles = 0;
+ uint8_t found_sequences = 0;
+
+ if (rach_config->restrictedSetConfig == 0) {
+ if (NCS == 0) return nb_preambles;
+ else {
+ r = L_ra/NCS;
+ printf(" found_sequences %u\n", (nb_preambles/r));
+ return (nb_preambles/r);
+ }
+ }
+ else{
+ index = rach_config->prach_RootSequenceIndex.choice.l839;
+ while (found_preambles < nb_preambles) {
+ u = table_63313[index%(L_ra-1)];
+
+ q = 0;
+ while (((q*u)%L_ra) != 1) q++;
+ if (q < 420) d_u = q;
+ else d_u = L_ra - q;
+
+ uint16_t n_group_ra = 0;
+ if (rach_config->restrictedSetConfig == 1) {
+ if ( (d_u<280) && (d_u>=NCS) ) {
+ n_shift_ra = d_u/NCS;
+ d_start = (d_u<<1) + (n_shift_ra * NCS);
+ n_group_ra = L_ra/d_start;
+ n_shift_ra_bar = max(0,(L_ra-(d_u<<1)-(n_group_ra*d_start))/L_ra);
+ } else if ( (d_u>=280) && (d_u<=((L_ra - NCS)>>1)) ) {
+ n_shift_ra = (L_ra - (d_u<<1))/NCS;
+ d_start = L_ra - (d_u<<1) + (n_shift_ra * NCS);
+ n_group_ra = d_u/d_start;
+ n_shift_ra_bar = min(n_shift_ra,max(0,(d_u- (n_group_ra*d_start))/NCS));
+ } else {
+ n_shift_ra = 0;
+ n_shift_ra_bar = 0;
+ }
+ w = n_shift_ra*n_group_ra + n_shift_ra_bar;
+ found_preambles += w;
+ found_sequences++;
+ }
+ else {
+ AssertFatal(1==0,"Procedure to find nb of sequences for restricted type B not implemented yet");
+ }
+ }
+ printf(" found_sequences %u\n", found_sequences);
+ return found_sequences;
+ }
+}
+
+
nr_bandentry_t nr_bandtable[] = {
{1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
{2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
@@ -373,13 +1531,19 @@ int32_t get_nr_uldl_offset(int nr_bandP)
void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
- int x_overhead) {
+ int x_overhead,
+ uint8_t nodata_dmrs,
+ uint8_t tb_scaling) {
LOG_D(MAC, "TBS calculation\n");
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_rel15 = &pdsch_pdu->pdsch_pdu_rel15;
uint16_t N_PRB_oh = x_overhead;
- uint8_t N_PRB_DMRS = (pdsch_rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
+ uint8_t N_PRB_DMRS;
+ if (nodata_dmrs)
+ N_PRB_DMRS = 12;
+ else
+ N_PRB_DMRS = (pdsch_rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
uint8_t N_sh_symb = pdsch_rel15->NrOfSymbols;
uint8_t Imcs = pdsch_rel15->mcsIndex[0];
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
@@ -401,8 +1565,9 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
R,
pdsch_rel15->rbSize,
N_sh_symb,
- N_PRB_DMRS,
+ N_PRB_DMRS, // FIXME // This should be multiplied by the number of dmrs symbols
N_PRB_oh,
+ tb_scaling,
pdsch_rel15->nrOfLayers)>>3;
pdsch_rel15->targetCodeRate[0] = R;
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
similarity index 53%
rename from openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h
rename to openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 6b043963b0..cc0dc5fd9e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -32,13 +32,8 @@
#ifndef __LAYER2_NR_MAC_COMMON_H__
#define __LAYER2_NR_MAC_COMMON_H__
-uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
-
-uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
-
-uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
-
-int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols);
+#include "NR_PDSCH-Config.h"
+#include "NR_ServingCellConfigCommon.h"
typedef enum {
NR_DL_DCI_FORMAT_1_0 = 0,
@@ -67,4 +62,50 @@ typedef enum {
NR_RNTI_TPC_SRS
} nr_rnti_type_t;
+uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
+
+void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
+
+uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
+
+uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
+
+int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols);
+
+int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
+
+int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
+
+uint16_t nr_dci_size(nr_dci_format_t format, nr_rnti_type_t rnti_type, uint16_t N_RB);
+
+void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
+ uint16_t *slot_period,
+ uint16_t *offset);
+
+int get_nr_prach_info_from_index(uint8_t index,
+ int frame,
+ int slot,
+ uint32_t pointa,
+ uint8_t mu,
+ uint8_t unpaired,
+ uint16_t *format,
+ uint8_t *start_symbol,
+ uint8_t *N_t_slot,
+ uint8_t *N_dur);
+
+uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
+ uint8_t nb_preambles,
+ uint8_t unpaired);
+
+int get_format0(uint8_t index, uint8_t unpaired);
+
+uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config);
+
+int get_num_dmrs(uint16_t dmrs_mask );
+uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
+int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength);
+
+uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
+uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
+
#endif
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
index 63c81def82..5c714e4a93 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
@@ -19,12 +19,12 @@
* contact@openairinterface.org
*/
-/*! \file extern.h
+/*! \file nr_mac_extern.h
* \brief NR mac externs
-* \author G. Casati
+* \author Navid Nikaein, Raymond Knopp, Guido Casati
* \date 2019
* \version 1.0
-* \email guido.casati@iis.fraunhofer.de
+* \email navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
@@ -32,10 +32,10 @@
#ifndef __NR_MAC_EXTERN_H__
#define __NR_MAC_EXTERN_H__
-//#include "PHY/defs_common.h"
-#include "nr_mac.h"
-#include "RRC/LTE/rrc_defs.h"
#include "common/ran_context.h"
+#include "nr_mac.h"
+
+/*#include "PHY/defs_common.h"*/
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
@@ -43,8 +43,6 @@ extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern UE_RRC_INST *UE_rrc_inst;
-extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
-extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern const int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34];
@@ -52,6 +50,7 @@ extern mac_rlc_am_muilist_t rlc_am_mui;
extern SCHEDULER_MODES global_scheduler_mode;
extern unsigned char NB_UE_INST;*/
+
extern unsigned char NB_INST;
extern unsigned char NB_eNB_INST;
extern unsigned char NB_RN_INST;
@@ -60,8 +59,15 @@ extern unsigned short NODE_ID[1];
/* Scheduler */
extern RAN_CONTEXT_t RC;
extern uint8_t nfapi_mode;
+extern mac_rlc_am_muilist_t rlc_am_mui;
+extern SCHEDULER_MODES global_scheduler_mode;
/*#if defined(PRE_SCD_THREAD)
+extern const int cqi_to_mcs[16];
+extern uint32_t RRC_CONNECTION_FLAG;
+extern uint8_t rb_table[34];
+
+#if defined(PRE_SCD_THREAD)
extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX];
extern uint8_t dlsch_ue_select_tbl_in_use;
extern uint8_t new_dlsch_ue_select_tbl_in_use;
@@ -69,4 +75,5 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
#endif*/
+
#endif //DEF_H
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index c983023034..f50c15df50 100755
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -31,11 +31,9 @@
*/
//#include "mac_defs.h"
-#include "mac_proto.h"
-
+#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC-CellGroupConfig.h"
-
-#include "../NR_MAC_gNB/nr_mac_common.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "SCHED_NR/phy_frame_config_nr.h"
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
@@ -151,8 +149,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
NR_ServingCellConfigCommon_t *scc = mac->scc;
int i;
- mac->phy_config.Mod_id = module_id;
- mac->phy_config.CC_id = cc_idP;
+ mac->phy_config.Mod_id = module_id;
+ mac->phy_config.CC_id = cc_idP;
// carrier config
@@ -203,12 +201,20 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
}
}
+ lte_frame_type_t frame_type;
+ uint16_t band;
+ int32_t offset;
+
+ get_band((cfg->carrier_config.dl_frequency)*1000,
+ &band,
+ &offset,
+ &frame_type);
+
// cell config
cfg->cell_config.phy_cell_id = *scc->physCellId;
- cfg->cell_config.frame_duplex_type = 1;
-
+ cfg->cell_config.frame_duplex_type = frame_type;
// SSB config
cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
@@ -270,6 +276,53 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
LOG_I(PHY,"TDD has been properly configurated\n");
}
+ // PRACH configuration
+
+ uint8_t nb_preambles = 64;
+ if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
+ nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
+
+ cfg->prach_config.prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
+
+ if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
+ cfg->prach_config.prach_sub_c_spacing = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
+ else
+ cfg->prach_config.prach_sub_c_spacing = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+ cfg->prach_config.restricted_set_config = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
+
+ switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
+ case 0 :
+ cfg->prach_config.num_prach_fd_occasions = 1;
+ break;
+ case 1 :
+ cfg->prach_config.num_prach_fd_occasions = 2;
+ break;
+ case 2 :
+ cfg->prach_config.num_prach_fd_occasions = 4;
+ break;
+ case 3 :
+ cfg->prach_config.num_prach_fd_occasions = 8;
+ break;
+ default:
+ AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM);
+ }
+
+ cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t));
+ for (i=0; iprach_config.num_prach_fd_occasions; i++) {
+ cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
+ if (cfg->prach_config.prach_sequence_length)
+ cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139;
+ else
+ cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
+
+ cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
+ cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
+ cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type);
+ //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
+ }
+
+ cfg->prach_config.ssb_per_rach = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
}
@@ -297,10 +350,11 @@ int nr_rrc_mac_config_req_ue(
if(spCell_ConfigP != NULL ){
mac->servCellIndex = *spCell_ConfigP->servCellIndex;
if (spCell_ConfigP->reconfigurationWithSync) {
- mac->scc = spCell_ConfigP->reconfigurationWithSync->spCellConfigCommon;
- config_common_ue(mac,module_id,cc_idP);
- mac->crnti = spCell_ConfigP->reconfigurationWithSync->newUE_Identity;
- LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
+ mac->rach_ConfigDedicated = spCell_ConfigP->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
+ mac->scc = spCell_ConfigP->reconfigurationWithSync->spCellConfigCommon;
+ config_common_ue(mac,module_id,cc_idP);
+ mac->crnti = spCell_ConfigP->reconfigurationWithSync->newUE_Identity;
+ LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
}
mac->scd = spCell_ConfigP->spCellConfigDedicated;
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index 405ea95eb1..a711561747 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -37,6 +37,21 @@
#include
#include
#include "platform_types.h"
+
+/* PHY */
+#include "PHY/defs_nr_common.h"
+
+/* IF */
+#include "NR_IF_Module.h"
+#include "fapi_nr_ue_interface.h"
+
+/* MAC */
+#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
+#include "LAYER2/MAC/mac.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
+
+/* RRC */
#include "NR_DRX-Config.h"
#include "NR_SchedulingRequestConfig.h"
#include "NR_BSR-Config.h"
@@ -48,11 +63,7 @@
#include "NR_PhysicalCellGroupConfig.h"
#include "NR_SpCellConfig.h"
#include "NR_ServingCellConfig.h"
-#include "fapi_nr_ue_interface.h"
-#include "NR_IF_Module.h"
-#include "../NR_MAC_gNB/nr_mac_common.h"
-#include "PHY/defs_nr_common.h"
-#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h"
+
#define NB_NR_UE_MAC_INST 1
/*!\brief Maximum number of logical channl group IDs */
@@ -61,6 +72,7 @@
/*!\brief value for indicating BSR Timer is not running */
#define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF)
+
typedef enum {
SFN_C_MOD_2_EQ_0,
SFN_C_MOD_2_EQ_1,
@@ -133,24 +145,27 @@ typedef struct {
#define MAX_NUM_BWP 2
typedef enum {
- RA_IDLE=0,
- WAIT_RAR=1,
- WAIT_CONTENTION_RESOLUTION=2
+ RA_UE_IDLE = 0,
+ WAIT_RAR = 1,
+ WAIT_CONTENTION_RESOLUTION = 2,
+ RA_SUCCEEDED = 3
} RA_state_t;
+
/*!\brief Top level UE MAC structure */
typedef struct {
NR_ServingCellConfigCommon_t *scc;
NR_ServingCellConfig_t *scd;
+ NR_RACH_ConfigDedicated_t *rach_ConfigDedicated;
int servCellIndex;
//// MAC config
- NR_DRX_Config_t *drx_Config;
+ NR_DRX_Config_t *drx_Config;
NR_SchedulingRequestConfig_t *schedulingRequestConfig;
- NR_BSR_Config_t *bsr_Config;
- NR_TAG_Config_t *tag_Config;
- NR_PHR_Config_t *phr_Config;
- NR_RNTI_Value_t *cs_RNTI;
- NR_MIB_t *mib;
+ NR_BSR_Config_t *bsr_Config;
+ NR_TAG_Config_t *tag_Config;
+ NR_PHR_Config_t *phr_Config;
+ NR_RNTI_Value_t *cs_RNTI;
+ NR_MIB_t *mib;
NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP];
NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP];
@@ -163,14 +178,75 @@ typedef struct {
SFN_C_TYPE type0_pdcch_ss_sfn_c;
uint32_t type0_pdcch_ss_n_c;
uint32_t type0_pdcch_consecutive_slots;
+ int rnti_type;
+
+ /* PDUs */
+ /// Outgoing CCCH pdu for PHY
+ CCCH_PDU CCCH_pdu;
+ ULSCH_PDU ulsch_pdu;
+
+ /* Random Access parameters */
/// state of RA procedure
RA_state_t ra_state;
- /// RA-rnti
+ /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB.
+ uint8_t RA_offset;
+ /// RA-rnti
uint16_t ra_rnti;
- /// Temporary CRNTI
+ /// Temporary CRNTI
uint16_t t_crnti;
- /// CRNTI
+ /// CRNTI
uint16_t crnti;
+ /// number of attempt for rach
+ uint8_t RA_attempt_number;
+ /// Random-access procedure flag
+ uint8_t RA_active;
+ /// Random-access window counter
+ int8_t RA_window_cnt;
+ /// Random-access Msg3 size in bytes
+ uint8_t RA_Msg3_size;
+ /// Random-access prachMaskIndex
+ uint8_t RA_prachMaskIndex;
+ /// Flag indicating Preamble set (A,B) used for first Msg3 transmission
+ uint8_t RA_usedGroupA;
+ /// BeamfailurerecoveryConfig
+ NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig;
+ /// Preamble Tx Counter
+ uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
+ /// Preamble Power Ramping Counter
+ uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER;
+ /// Random-access backoff counter
+ int16_t RA_backoff_indicator;
+ /// Random-access backoff counter
+ int16_t RA_backoff_cnt;
+ /// Random-access variable for window calculation (frame of last change in window counter)
+ uint32_t RA_tx_frame;
+ /// Random-access variable for window calculation (subframe of last change in window counter)
+ uint8_t RA_tx_subframe;
+ /// Scheduled RX frame for RA Msg2
+ uint16_t msg2_rx_frame;
+ /// Scheduled RX slot for RA Msg2
+ uint16_t msg2_rx_slot;
+ /// Random-access Group B maximum path-loss
+ /// Random-access variable for backoff (frame of last change in backoff counter)
+ uint32_t RA_backoff_frame;
+ /// Random-access variable for backoff (subframe of last change in backoff counter)
+ uint8_t RA_backoff_subframe;
+ /// Random-access Group B maximum path-loss
+ uint16_t RA_maxPL;
+ /// Random-access Contention Resolution Timer active flag
+ uint8_t RA_contention_resolution_timer_active;
+ /// Random-access Contention Resolution Timer count value
+ uint8_t RA_contention_resolution_cnt;
+ /// Msg3 Delta Preamble
+ int8_t deltaPreamble_Msg3;
+ /// Received TPC command (in dB) from RAR
+ int8_t Msg3_TPC;
+ /// Flag to monitor if matching RAPID was received in RAR
+ uint8_t RA_RAPID_found;
+ /// Flag to monitor if BI was received in RAR
+ uint8_t RA_BI_found;
+ /// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot
+ uint8_t generate_nr_prach;
//// FAPI-like interface message
fapi_nr_tx_request_t tx_request;
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 3c625ec2ff..38c9244014 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -84,23 +84,9 @@ NR_UE_MAC_INST_t *get_mac_inst(
/**\brief called at each slot, slot length based on numerology. now use u=0, scs=15kHz, slot=1ms
performs BSR/SR/PHR procedures, random access procedure handler and DLSCH/ULSCH procedures.
- \param module_id module id
- \param gNB_index corresponding gNB index
- \param cc_id component carrier id
- \param rx_frame receive frame number
- \param rx_slot receive slot number
- \param tx_frame transmit frame number
- \param tx_slot transmit slot number*/
-NR_UE_L2_STATE_t nr_ue_scheduler(
- const module_id_t module_id,
- const uint8_t gNB_index,
- const int cc_id,
- const frame_t rx_frame,
- const slot_t rx_slot,
- const int32_t ssb_index,
- const frame_t tx_frame,
- const slot_t tx_slot);
-
+ \param dl_info DL indication
+ \param ul_info UL indication*/
+NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info);
/* \brief Get SR payload (0,1) from UE MAC
@param Mod_id Instance id of UE in machine
@@ -124,8 +110,6 @@ uint32_t get_ssb_slot(uint32_t ssb_index);
uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
-
-
/* \brief Get payload (MAC PDU) from UE PHY
@param module_idP Instance id of UE in machine
@param CC_id Component Carrier index
@@ -154,9 +138,23 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
uint8_t gNB_index,
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment);
+
+uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
+ uint8_t *pdu,
+ uint8_t num_sdus,
+ uint16_t *sdu_lengths,
+ uint8_t *sdu_lcids,
+ uint8_t power_headroom,
+ uint16_t crnti,
+ uint16_t truncated_bsr,
+ uint16_t short_bsr,
+ uint16_t long_bsr,
+ unsigned short post_padding,
+ uint16_t buflen);
+
int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len);
-void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot);
+void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot);
void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int dci_format,
@@ -175,5 +173,95 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
int nrofDownlinkSlots, int nrofDownlinkSymbols,
int nrofUplinkSlots, int nrofUplinkSymbols);
+/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
+ @param Mod_id Module id of UE
+ @returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
+*/
+int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t module_idP, uint8_t CC_id);
+
+/** \brief Function to compute DELTA_PREAMBLE from 38.321 subclause 7.3
+ (for RA power ramping procedure and Msg3 PUSCH power control policy)
+ @param Mod_id Module id of UE
+ @returns DELTA_PREAMBLE
+*/
+int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format);
+
+/* Random Access */
+
+/* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x
+and fills the PRACH PDU per each FD occasion.
+@param module_idP Index of UE instance
+@param frameP Frame index
+@param slotP Slot index
+@returns void
+*/
+void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
+
+/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
+@param Mod_id Index of UE instance
+@param CC_id Index to a component carrier
+@param frame Frame index
+@param ra_rnti RA_RNTI value
+@param dlsch_buffer Pointer to dlsch_buffer containing RAR PDU
+@param t_crnti Pointer to PHY variable containing the T_CRNTI
+@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of
+random-access procedure
+@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload
+@returns timing advance or 0xffff if preamble doesn't match
+*/
+uint16_t nr_ue_process_rar(module_id_t mod_id,
+ int CC_id,
+ frame_t frameP,
+ uint8_t * dlsch_buffer,
+ rnti_t * t_crnti,
+ uint8_t preamble_index,
+ uint8_t * selected_rar_buffer);
+
+void nr_process_rar(nr_downlink_indication_t *dl_info);
+
+void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame);
+
+void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
+
+void nr_ra_succeeded(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
+
+/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure.
+If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
+attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB
+index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for
+andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
+@param mod_id Index of UE instance
+@param CC_id Component Carrier Index
+@param frame
+@param gNB_id gNB index
+@param nr_tti_tx slot for PRACH transmission
+@returns indication to generate PRACH to phy */
+uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
+ module_id_t mod_id,
+ int CC_id,
+ UE_MODE_t UE_mode,
+ frame_t frame,
+ uint8_t gNB_id,
+ int nr_tti_tx);
+
+/* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321).
+@param module_idP Index of UE instance
+@param CC_id Component Carrier Index
+@param gNB_index gNB index
+@param t_id
+@param rach_ConfigDedicated
+@returns void */
+void nr_get_prach_resources(module_id_t mod_id,
+ int CC_id,
+ uint8_t gNB_id,
+ uint8_t t_id,
+ uint8_t first_Msg3,
+ NR_PRACH_RESOURCES_t *prach_resources,
+ NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
+
+void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
+
+void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
+
#endif
/** @}*/
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
new file mode 100644
index 0000000000..9d7f3264c5
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
@@ -0,0 +1,153 @@
+/*
+ * 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 nr_l1_helper.c
+* \brief PHY helper functions for PRACH adapted to NR
+* \author Guido Casati
+* \date 2019
+* \version 2.0
+* \email guido.casati@iis.fraunhofer.de
+* @ingroup _mac
+
+*/
+
+#include "PHY/defs_nr_common.h"
+
+#include "mac_defs.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
+
+/* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */
+int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format){
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+ NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
+ int prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1;
+ uint8_t prachConfigIndex, mu;
+
+ AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+
+ // SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211
+
+ switch (scs){
+ case NR_SubcarrierSpacing_kHz15:
+ mu = 0;
+ break;
+
+ case NR_SubcarrierSpacing_kHz30:
+ mu = 1;
+ break;
+
+ case NR_SubcarrierSpacing_kHz60:
+ mu = 2;
+ break;
+
+ case NR_SubcarrierSpacing_kHz120:
+ mu = 3;
+ break;
+
+ case NR_SubcarrierSpacing_kHz240:
+ mu = 4;
+ break;
+
+ case NR_SubcarrierSpacing_spare3:
+ mu = 5;
+ break;
+
+ case NR_SubcarrierSpacing_spare2:
+ mu = 6;
+ break;
+
+ case NR_SubcarrierSpacing_spare1:
+ mu = 7;
+ break;
+
+ default:
+ AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %lu\n", scs);
+ }
+
+ // Preamble formats given by prach_ConfigurationIndex and tables 6.3.3.2-2 and 6.3.3.2-2 in TS 38.211
+
+ prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
+
+ if (prach_sequence_length == 0) {
+ switch (prach_format) {
+ AssertFatal(prach_format < 4, "Illegal PRACH format %d for sequence length 839\n", prach_format);
+
+ // long preamble formats
+ case 0:
+ case 3:
+ return 0;
+
+ case 1:
+ return -3;
+
+ case 2:
+ return -6;
+ }
+ } else {
+ switch (prach_format) { // short preamble formats
+ case 0:
+ case 3:
+ return 8 + 3*mu;
+
+ case 1:
+ case 4:
+ case 8:
+ return 5 + 3*mu;
+
+ case 2:
+ case 5:
+ return 3 + 3*mu;
+
+ case 6:
+ return 3*mu;
+
+ case 7:
+ return 5 + 3*mu;
+
+ default:
+ AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, prach_format, prachConfigIndex);
+ }
+ }
+ return 0;
+}
+
+/* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */
+int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, uint8_t CC_id){
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+ int8_t receivedTargerPower, delta_preamble;
+ long preambleReceivedTargetPower;
+
+ AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id);
+
+ preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
+ delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format);
+
+ receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (mac->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
+
+ return receivedTargerPower;
+}
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
new file mode 100644
index 0000000000..6a3f4ad902
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -0,0 +1,643 @@
+/*
+ * 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 ra_procedures.c
+ * \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15)
+ * \author R. Knopp, Navid Nikaein, Guido Casati
+ * \date 2019
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
+ * \note
+ * \warning
+ */
+
+#include "mac.h"
+
+/*
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "PHY_INTERFACE/phy_interface_extern.h"
+#include "SCHED_UE/sched_UE.h"
+#include "COMMON/mac_rrc_primitives.h"
+#include "RRC/LTE/rrc_extern.h"
+#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
+#include "common/utils/LOG/log.h"
+#include "UTIL/OPT/opt.h"
+#include "OCG.h"
+#include "OCG_extern.h"
+#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/
+
+/* Tools */
+#include "SIMULATION/TOOLS/sim.h" // for taus
+
+/* RRC */
+#include "NR_RACH-ConfigCommon.h"
+
+/* PHY */
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+#include "PHY/defs_common.h"
+#include "PHY/defs_nr_common.h"
+#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
+
+/* MAC */
+#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
+
+extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
+extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
+extern const uint16_t nr_slots_per_frame[5];
+
+//extern uint8_t nfapi_mode;
+
+void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
+
+// WIP
+// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
+// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
+void nr_get_prach_resources(module_id_t mod_id,
+ int CC_id,
+ uint8_t gNB_id,
+ uint8_t t_id,
+ uint8_t first_Msg3,
+ NR_PRACH_RESOURCES_t *prach_resources,
+ NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
+ NR_RACH_ConfigGeneric_t *rach_ConfigGeneric;
+
+ // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo
+
+ int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0;
+ uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, prach_ConfigIndex, SFN_nbr, Msg3_size;
+
+ AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
+ nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+ rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric;
+
+ // NR_RSRP_Range_t rsrp_ThresholdSSB; // todo
+
+ ///////////////////////////////////////////////////////////
+ //////////* UE Random Access Resource Selection *//////////
+ ///////////////////////////////////////////////////////////
+
+ // todo:
+ // - switch initialisation cases
+ // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
+ // --- SSB selection, set prach_resources->ra_PreambleIndex
+ // -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000
+ // --- set PREAMBLE_INDEX to ra_preamble_index
+ // --- select the SSB signalled by PDCCH
+ // -- RA initiated for SI request:
+ // --- SSB selection, set prach_resources->ra_PreambleIndex
+
+ if (rach_ConfigDedicated) {
+ //////////* Contention free RA *//////////
+ // - the PRACH preamble for the UE to transmit is set through RRC configuration
+ // - this is the default mode in current implementation!
+ // Operation for contention-free RA resources when:
+ // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
+ // - available CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
+ // - network controlled Mobility
+ uint8_t cfra_ssb_resource_idx = 0;
+ prach_resources->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex;
+ LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-free random access procedure... \n", prach_resources->ra_PreambleIndex);
+ } else {
+ //////////* Contention-based RA preamble selection *//////////
+ // todo:
+ // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB
+ // - todo determine next available PRACH occasion
+
+ // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
+
+ Msg3_size = mac->RA_Msg3_size;
+
+ numberOfRA_Preambles = 64;
+ if(nr_rach_ConfigCommon->totalNumberOfRA_Preambles != NULL)
+ numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
+
+ if (!nr_rach_ConfigCommon->groupBconfigured) {
+ noGroupB = 1;
+ } else {
+ // RA preambles group B is configured
+ // - Defining the number of RA preambles in RA Preamble Group A for each SSB */
+ sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
+ switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
+ /* - Threshold to determine the groups of RA preambles */
+ case 0:
+ messageSizeGroupA = 56;
+ break;
+ case 1:
+ messageSizeGroupA = 144;
+ break;
+ case 2:
+ messageSizeGroupA = 208;
+ break;
+ case 3:
+ messageSizeGroupA = 256;
+ break;
+ case 4:
+ messageSizeGroupA = 282;
+ break;
+ case 5:
+ messageSizeGroupA = 480;
+ break;
+ case 6:
+ messageSizeGroupA = 640;
+ break;
+ case 7:
+ messageSizeGroupA = 800;
+ break;
+ case 8:
+ messageSizeGroupA = 1000;
+ break;
+ case 9:
+ messageSizeGroupA = 72;
+ break;
+ default:
+ AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
+ /* todo cases 10 -15*/
+ }
+
+ /* Power offset for preamble selection in dB */
+ messagePowerOffsetGroupB = -9999;
+ switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
+ case 0:
+ messagePowerOffsetGroupB = -9999;
+ break;
+ case 1:
+ messagePowerOffsetGroupB = 0;
+ break;
+ case 2:
+ messagePowerOffsetGroupB = 5;
+ break;
+ case 3:
+ messagePowerOffsetGroupB = 8;
+ break;
+ case 4:
+ messagePowerOffsetGroupB = 10;
+ break;
+ case 5:
+ messagePowerOffsetGroupB = 12;
+ break;
+ case 6:
+ messagePowerOffsetGroupB = 15;
+ break;
+ case 7:
+ messagePowerOffsetGroupB = 18;
+ break;
+ default:
+ AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
+ }
+
+ // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
+ mac->deltaPreamble_Msg3 = 0;
+ deltaPreamble_Msg3 = mac->deltaPreamble_Msg3;
+ }
+
+ PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
+
+ /* Msg3 has not been transmitted yet */
+ if (first_Msg3 == 1) {
+ if (noGroupB == 1) {
+ // use Group A preamble
+ prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
+ mac->RA_usedGroupA = 1;
+ } else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) {
+ // Group B is configured and RA preamble Group A is used
+ // - todo add condition on CCCH_sdu_size for initiation by CCCH
+ prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
+ mac->RA_usedGroupA = 1;
+ } else {
+ // Group B preamble is configured and used
+ // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
+ // the remaining belong to RA Preambles Group B
+ prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
+ mac->RA_usedGroupA = 0;
+ }
+ } else { // Msg3 is being retransmitted
+ if (mac->RA_usedGroupA == 1 && noGroupB == 1) {
+ prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
+ } else if (mac->RA_usedGroupA == 1 && noGroupB == 0){
+ prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
+ } else {
+ prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
+ }
+ }
+ LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex);
+ }
+
+ // todo determine next available PRACH occasion
+ // - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
+ // - else if SSB is selected above
+ // - else if CSI-RS is selected above
+
+ /////////////////////////////////////////////////////////////////////////////
+ //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
+ /////////////////////////////////////////////////////////////////////////////
+ // todo:
+ // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
+ // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
+ // - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded)
+
+ if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
+ mac->RA_PREAMBLE_POWER_RAMPING_COUNTER++;
+
+ prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
+
+ // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
+ // 1) this does not apply to contention-free RA Preamble for beam failure recovery request
+ // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
+
+ prach_ConfigIndex = rach_ConfigGeneric->prach_ConfigurationIndex;
+
+ // ra_RNTI computation
+ // - todo: this is for TDD FR1 only
+ // - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier
+ // - f_id: index of the PRACH occasion in the frequency domain
+ // - s_id is starting symbol of the PRACH occasion [0...14]
+ // - t_id is the first slot of the PRACH occasion in a system frame [0...80]
+
+ ul_carrier_id = 0; // NUL
+ f_id = rach_ConfigGeneric->msg1_FrequencyStart;
+ SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
+ s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5];
+
+ // Pick the first slot of the PRACH occasion in a system frame
+ for (i = 0; i < 10; i++){
+ if (((SFN_nbr & (1 << i)) >> i) == 1){
+ t_id = 2*i;
+ break;
+ }
+ }
+ prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
+ mac->ra_rnti = prach_resources->ra_RNTI;
+
+ LOG_D(MAC, "Computed ra_RNTI is %x \n", prach_resources->ra_RNTI);
+}
+
+// TbD: RA_attempt_number not used
+void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
+ AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ mac->ra_state = WAIT_RAR;
+ // Start contention resolution timer
+ mac->RA_attempt_number++;
+}
+
+void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
+ AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+ LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ // start contention resolution timer
+ mac->RA_contention_resolution_cnt = 0;
+ mac->RA_contention_resolution_timer_active = 1;
+}
+
+/////////////////////////////////////////////////////////////////////////
+///////* Random Access Preamble Initialization (5.1.1 TS 38.321) *///////
+/////////////////////////////////////////////////////////////////////////
+/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300)
+/// Only one RA procedure is ongoing at any point in time in a MAC entity
+/// the RA procedure on a SCell shall only be initiated by PDCCH order
+/// in the current implementation, RA is contention free only
+
+// WIP
+// todo TS 38.321:
+// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX
+// - BWP operation (subclause 5.15 TS 38.321)
+// - handle initialization by beam failure recovery
+// - handle initialization by handover
+// - handle transmission on DCCH using PRACH (during handover, or sending SR for example)
+// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader)
+// - fix rrc data req logic
+// - retrieve TBS
+// - add mac_rrc_nr_data_req_ue, etc ...
+// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
+uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
+ module_id_t mod_id,
+ int CC_id,
+ UE_MODE_t UE_mode,
+ frame_t frame,
+ uint8_t gNB_id,
+ int nr_tti_tx){
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
+ uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload;
+ //uint8_t ra_ResponseWindow;
+ uint16_t size_sdu = 0;
+ unsigned short post_padding;
+ //fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+ NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
+ //NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
+ NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = mac->rach_ConfigDedicated;
+
+ // int32_t frame_diff = 0;
+
+ uint8_t sdu_lcids[NB_RB_MAX] = {0};
+ uint16_t sdu_lengths[NB_RB_MAX] = {0};
+ int TBS_bytes = 848, header_length_total, num_sdus, offset, preambleTransMax, mac_ce_len;
+
+ AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
+
+ if (UE_mode == PRACH && prach_resources->init_msg1) {
+
+ LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active);
+
+ AssertFatal(setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
+
+ if (mac->RA_active == 0) {
+ /* RA not active - checking if RRC is ready to initiate the RA procedure */
+
+ LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n");
+
+ mac->RA_RAPID_found = 0;
+
+ /* Set RA_PREAMBLE_POWER_RAMPING_STEP */
+ switch (rach_ConfigGeneric->powerRampingStep){ // in dB
+ case 0:
+ prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
+ break;
+ case 1:
+ prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
+ break;
+ case 2:
+ prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
+ break;
+ case 3:
+ prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
+ break;
+ }
+
+ prach_resources->RA_PREAMBLE_BACKOFF = 0;
+ prach_resources->RA_SCALING_FACTOR_BI = 1;
+ prach_resources->RA_PCMAX = 0; // currently hardcoded to 0
+
+ payload = (uint8_t*) &mac->CCCH_pdu.payload;
+
+ mac_ce_len = 0;
+ num_sdus = 1;
+ post_padding = 1;
+
+ if (0){
+ // initialisation by RRC
+ // CCCH PDU
+ // size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id,
+ // CC_id,
+ // frame,
+ // CCCH,
+ // 1,
+ // mac_sdus,
+ // gNB_id,
+ // 0);
+ LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
+ } else {
+ // fill ulsch_buffer with random data
+ for (int i = 0; i < TBS_bytes; i++){
+ mac_sdus[i] = (unsigned char) (lrand48()&0xff);
+ }
+ //Sending SDUs with size 1
+ //Initialize elements of sdu_lcids and sdu_lengths
+ sdu_lcids[0] = lcid;
+ sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
+ header_length_total += 2 + (sdu_lengths[0] >= 128);
+ size_sdu += sdu_lengths[0];
+ }
+
+ //mac->RA_tx_frame = frame;
+ //mac->RA_tx_subframe = nr_tti_tx;
+ //mac->RA_backoff_frame = frame;
+ //mac->RA_backoff_subframe = nr_tti_tx;
+
+ if (size_sdu > 0) {
+
+ LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame);
+
+ mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
+ mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
+ mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
+ mac->RA_prachMaskIndex = 0;
+ // todo: add the backoff condition here
+ mac->RA_backoff_cnt = 0;
+ mac->RA_active = 1;
+ prach_resources->Msg3 = payload;
+
+ nr_get_RA_window(mac);
+
+ // Fill in preamble and PRACH resources
+ if (mac->generate_nr_prach)
+ nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated);
+
+ offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer
+ (uint8_t *) payload, // UL MAC pdu pointer
+ num_sdus, // num sdus
+ sdu_lengths, // sdu length
+ sdu_lcids, // sdu lcid
+ 0, // power headroom
+ 0, // crnti
+ 0, // truncated bsr
+ 0, // short bsr
+ 0, // long_bsr
+ post_padding,
+ 0);
+
+ // Padding: fill remainder with 0
+ if (post_padding > 0){
+ for (int j = 0; j < (TBS_bytes - offset); j++)
+ payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
+ }
+ }
+ } else { // RACH is active
+
+ ////////////////////////////////////////////////////////////////
+ /////* Random Access Response reception (5.1.4 TS 38.321) */////
+ ////////////////////////////////////////////////////////////////
+ // Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER
+ // and RA_backoff_cnt
+ // todo:
+ // - handle beam failure recovery request
+ // - handle DL assignment on PDCCH for RA-RNTI
+ // - handle backoff and raResponseWindow params
+ // - disabled contention resolution as OAI NSA is contention-free based
+
+ // LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
+ // mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe);
+
+ if (mac->RA_BI_found){
+ prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * mac->RA_backoff_indicator;
+ } else {
+ prach_resources->RA_PREAMBLE_BACKOFF = 0;
+ }
+
+ if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
+
+ // mac->ra_state = WAIT_CONTENTION_RESOLUTION;
+ LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR successfully received \n", mod_id, frame, nr_tti_tx);
+
+ } else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
+
+ LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception failed \n", mod_id, frame, nr_tti_tx);
+
+ mac->ra_state = RA_UE_IDLE;
+ mac->RA_PREAMBLE_TRANSMISSION_COUNTER++;
+
+ preambleTransMax = -1;
+ switch (rach_ConfigGeneric->preambleTransMax) {
+ case 0:
+ preambleTransMax = 3;
+ break;
+ case 1:
+ preambleTransMax = 4;
+ break;
+ case 2:
+ preambleTransMax = 5;
+ break;
+ case 3:
+ preambleTransMax = 6;
+ break;
+ case 4:
+ preambleTransMax = 7;
+ break;
+ case 5:
+ preambleTransMax = 8;
+ break;
+ case 6:
+ preambleTransMax = 10;
+ break;
+ case 7:
+ preambleTransMax = 20;
+ break;
+ case 8:
+ preambleTransMax = 50;
+ break;
+ case 9:
+ preambleTransMax = 100;
+ break;
+ case 10:
+ preambleTransMax = 200;
+ break;
+ }
+
+ // Resetting RA window
+ nr_get_RA_window(mac);
+
+ if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
+ LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax);
+ mac->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
+ mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
+ prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1; // 2 dB increment
+ prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
+ }
+
+ // compute backoff parameters
+ // if (mac->RA_backoff_cnt > 0){
+ // frame_diff = (sframe_t) frame - mac->RA_backoff_frame;
+ // if (frame_diff < 0) frame_diff = -frame_diff;
+ // mac->RA_backoff_frame = frame;
+ // mac->RA_backoff_subframe = nr_tti_tx;
+ // }
+ // compute RA window parameters
+ // if (mac->RA_window_cnt > 0){
+ // frame_diff = (frame_t) frame - mac->RA_tx_frame;
+ // if (frame_diff < 0) frame_diff = -frame_diff;
+ // mac->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - mac->RA_tx_subframe));
+ // LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, mac->RA_window_cnt);
+ // }
+
+ // mac->RA_tx_frame = frame;
+ // mac->RA_tx_subframe = nr_tti_tx;
+
+ // Fill in preamble and PRACH resources
+ if (mac->generate_nr_prach)
+ nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
+
+ } else {
+
+ mac->RA_window_cnt--;
+
+ LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n",
+ mod_id,
+ frame,
+ nr_tti_tx,
+ mac->RA_window_cnt);
+
+ // Fill in preamble and PRACH resources
+ if (mac->generate_nr_prach)
+ nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
+
+ }
+ }
+ } else if (UE_mode == PUSCH) {
+ LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id);
+ AssertFatal(1 == 0, "");
+ }
+ return mac->generate_nr_prach;
+}
+
+void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
+
+ uint8_t mu, ra_ResponseWindow;
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+ NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
+ NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
+
+ ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
+
+ if (setup->msg1_SubcarrierSpacing)
+ mu = *setup->msg1_SubcarrierSpacing;
+ else
+ mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+ mac->RA_window_cnt = mac->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB
+
+ switch (ra_ResponseWindow) {
+ case 0:
+ mac->RA_window_cnt += 1;
+ break;
+ case 1:
+ mac->RA_window_cnt += 2;
+ break;
+ case 2:
+ mac->RA_window_cnt += 4;
+ break;
+ case 3:
+ mac->RA_window_cnt += 8;
+ break;
+ case 4:
+ mac->RA_window_cnt += 10;
+ break;
+ case 5:
+ mac->RA_window_cnt += 20;
+ break;
+ case 6:
+ mac->RA_window_cnt += 40;
+ break;
+ case 7:
+ mac->RA_window_cnt += 80;
+ break;
+ }
+}
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
index 396e06ff09..a98a2b1211 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
@@ -21,11 +21,11 @@
/* \file nr_ue_dci_configuration.c
* \brief functions for generating dci search procedures based on RRC Serving Cell Group Configuration
- * \author R. Knopp
+ * \author R. Knopp, G. Casati
* \date 2020
- * \version 0.1
- * \company Eurecom
- * \email: knopp@eurecom.fr
+ * \version 0.2
+ * \company Eurecom, Fraunhofer IIS
+ * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
@@ -35,6 +35,8 @@
#include "assertions.h"
#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "mac_defs.h"
+#include "common/utils/nr/nr_common.h"
+#include "executables/softmodem-common.h"
#include
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
@@ -59,125 +61,218 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd
}
-void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot) {
+void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) {
- // check if DL slot
- if (is_nr_DL_slot(mac->scc,slot)==1) {
+ NR_ServingCellConfig_t *scd = mac->scd;
+ NR_BWP_Downlink_t *bwp;
+ NR_BWP_DownlinkCommon_t *bwp_Common;
+ NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated;
+ NR_SetupRelease_PDCCH_Config_t *pdcch_Config;
+ NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon;
+ struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList;
+ struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList;
+ struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList;
+ NR_SearchSpace_t *NR_SearchSpace;
+ NR_ControlResourceSet_t *coreset;
+
+ fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
+
+ uint8_t bwp_id = 1;
+ int ss_id, sps;
+
+ // get PDCCH configuration(s) (Coreset, SearchSpace, etc...) from BWP Dedicated in serving cell config dedicated (scd)
+ // get BWP 1, Coreset ID 0, SearchSpace ID 0 (i.e. configured in MIB and in ServingCellConfigCommon)
+
+ // Check dedicated DL BWP
+ if (mac->DLbwp[0] == NULL) {
+ NR_SearchSpace_t *ss;
+ int ss_id = 0;
+
+ AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n");
+ AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count);
+ mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1];
+
+ dl_bwp_Dedicated = mac->DLbwp[0]->bwp_Dedicated;
+ AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n");
+
+ bwp_Common = mac->DLbwp[0]->bwp_Common;
+ AssertFatal(bwp_Common != NULL, "bwp_Common is null\n");
+
+ pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
+ AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n");
+
+ pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
+ AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n");
+ AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n");
+
+ controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList;
+ AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n");
+
+ AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count);
+
+ mac->coreset[0][0] = controlResourceSetToAddModList->list.array[0];
+ coreset = mac->coreset[0][0];
+ AssertFatal(coreset != NULL, "coreset[0][0] is null\n");
- // get BWP 1, Coreset 0, SearchSpace 0
- if (mac->DLbwp[0]==NULL) {
- AssertFatal(mac->scd->downlinkBWP_ToAddModList!=NULL,"downlinkBWP_ToAddModList is null\n");
- AssertFatal(mac->scd->downlinkBWP_ToAddModList->list.count==1,"downlinkBWP_ToAddModList->list->count is %d\n",
- mac->scd->downlinkBWP_ToAddModList->list.count);
- mac->DLbwp[0] = mac->scd->downlinkBWP_ToAddModList->list.array[0];
- AssertFatal(mac->DLbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n");
- AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config!=NULL,"pdcch_Config is null\n");
- AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL,"controlResourceSetToAddModList is null\n");
- AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count==1,"controlResourceSetToAddModList->list.count=%d\n",
- mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count);
- mac->coreset[0][0] = mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[0];
- AssertFatal(mac->coreset[0][0]!=NULL,"coreset[0][0] is null\n");
-
- AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
- AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
- "searchPsacesToAddModList is empty\n");
- NR_SearchSpace_t *ss;
- int ss_id=0;
- AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.countDLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count);
- for (int i=0;iDLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
- ss=mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
- AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
- AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
- AssertFatal(*ss->controlResourceSetId == mac->coreset[0][0]->controlResourceSetId,"ss->controlResourceSetId is unknown\n");
- mac->SSpace[0][0][ss_id] = ss;
- ss_id++;
- }
- }
- if (mac->ULbwp[0]==NULL) {
- AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList!=NULL,"uplinkBWP_ToAddModList is null\n");
- AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count==1,"uplinkBWP_ToAddModList->list->count is %d\n",
- mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count);
- mac->ULbwp[0] = mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
- AssertFatal(mac->ULbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n");
- }
- // check search spaces
-
- int ss_id=0;
- fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
- int sps =mac->DLbwp[0]->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
-
- while(mac->SSpace[0][0][ss_id]!=NULL &&
- ss_id < mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count) {
-
- AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
- AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
-
+ searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
+ AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n");
+ AssertFatal(searchSpacesToAddModList->list.count > 0, "searchSpacesToAddModList is empty\n");
+ AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count);
+
+ for (int i = 0; i < searchSpacesToAddModList->list.count; i++) {
+ ss = searchSpacesToAddModList->list.array[i];
+ AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
+ AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
+ AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
+ mac->SSpace[0][0][ss_id] = ss;
ss_id++;
}
- if (mac->ra_state == WAIT_RAR) {
- // check for RAR
- rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
- rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot);
- dl_config->number_pdus = dl_config->number_pdus + 1;
+ }
+
+ // Check dedicated UL BWP
+ if (mac->ULbwp[0] == NULL) {
+ uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList;
+ AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n");
+ AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count);
+ mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[bwp_id - 1];
+ AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n");
+ }
+
+ bwp = mac->DLbwp[0];
+ bwp_Common = bwp->bwp_Common;
+ pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
+ dl_bwp_Dedicated = bwp->bwp_Dedicated;
+ pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
+ searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
+
+ // check USSs
+ ss_id = 0;
+ NR_SearchSpace = mac->SSpace[0][0][ss_id];
+ while(NR_SearchSpace != NULL && ss_id < searchSpacesToAddModList->list.count) {
+ AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n");
+ AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n");
+ ss_id++;
+ }
+
+ if (mac->crnti > 0) {
+
+ NR_SearchSpace_t *css;
+ NR_SearchSpace_t *uss = NULL;
+ NR_ServingCellConfigCommon_t *scc;
+ NR_SearchSpaceId_t ra_SearchSpaceId;
+ rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
+ uint16_t monitoringSymbolsWithinSlot;
+ uint8_t add_dci = 1;
+
+ AssertFatal(mac->scc != NULL, "scc is null\n");
+
+ scc = mac->scc;
+ rel15->dci_format = NR_DL_DCI_FORMAT_1_0;
+
+ // CoReSet configuration
+ coreset = mac->coreset[0][0];
+ rel15->coreset.duration = coreset->duration;
+ for (int i = 0; i < 6; i++)
+ rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i];
+
+ rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED;
+
+ if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) {
+ struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved;
+ rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize);
+ rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize);
+ AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n");
+ rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId;
+ } else {
+ rel15->coreset.RegBundleSize = 0;
+ rel15->coreset.InterleaverSize = 0;
+ rel15->coreset.ShiftIndex = 0;
}
- else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION) {
- rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
+
+ rel15->coreset.CoreSetType = 1;
+ rel15->coreset.precoder_granularity = coreset->precoderGranularity;
+
+ if (mac->ra_state == WAIT_RAR){
+
+ NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
+ struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n");
+
+ ra_SearchSpaceId = *pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
+
+ // fetch the CSS for RA from the CSS list
+ for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
+ css = commonSearchSpaceList->list.array[i];
+ if(css->searchSpaceId == ra_SearchSpaceId)
+ break;
+ }
+
+ // check CSSs
+ if(css != NULL) {
+ AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n");
+ AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n");
+ }
+
+ if (frame == mac->msg2_rx_frame && slot == mac->msg2_rx_slot){
+ sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+ monitoringSymbolsWithinSlot = (css->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (css->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
+ rel15->rnti = mac->ra_rnti;
+ rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
+ rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); // NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
+ rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
+ rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_RA, rel15->BWPSize);
+ for (int i = 0; i < sps; i++)
+ if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
+ rel15->coreset.StartSymbolIndex = i;
+ break;
+ }
+ fill_dci_search_candidates(css, rel15);
+ } else {
+ add_dci = 0;
+ }
+ } else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION){
+
rel15->rnti = mac->t_crnti;
- dl_config->number_pdus = dl_config->number_pdus + 1;
- }
- if (mac->crnti>0) {
- rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
+
+ } else {
+
rel15->rnti = mac->crnti;
- rel15->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
- rel15->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
- rel15->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+ rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275);
+ rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275);
+ rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
+ rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_C, rel15->BWPSize);
// get UE-specific search space
- for (ss_id=0;ss_idSSpace[0][0][ss_id]!=NULL;ss_id++)
- if (mac->SSpace[0][0][ss_id]->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break;
- AssertFatal(ss_idSSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
- (mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
-
- for (int i=0; i>(sps-1-i))&1) {
- rel15->coreset.StartSymbolIndex=i;
- break;
- }
- rel15->coreset.duration = mac->coreset[0][0]->duration;
- for (int i=0;i<6;i++)
- rel15->coreset.frequency_domain_resource[i] = mac->coreset[0][0]->frequencyDomainResources.buf[i];
-
- rel15->coreset.CceRegMappingType = mac->coreset[0][0]->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
- FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED;
- if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) {
- rel15->coreset.RegBundleSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
- rel15->coreset.InterleaverSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize);
- AssertFatal(mac->scc->physCellId != NULL,"mac->scc->physCellId is null\n");
- rel15->coreset.ShiftIndex = mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex : *mac->scc->physCellId;
+ for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[0][0][ss_id] != NULL; ss_id++){
+ uss = mac->SSpace[0][0][ss_id];
+ if (uss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break;
}
- else {
- rel15->coreset.RegBundleSize = 0;
- rel15->coreset.InterleaverSize = 0;
- rel15->coreset.ShiftIndex = 0;
- }
- rel15->coreset.CoreSetType = 1;
- rel15->coreset.precoder_granularity = mac->coreset[0][0]->precoderGranularity;
- if (mac->coreset[0][0]->pdcch_DMRS_ScramblingID)
- rel15->coreset.pdcch_dmrs_scrambling_id = *mac->coreset[0][0]->pdcch_DMRS_ScramblingID;
+ AssertFatal(ss_id < FAPI_NR_MAX_SS_PER_CORESET, "couldn't find a UE-specific SS\n");
+ sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+ // for SPS=14 8 MSBs in positions 13 down to 6
+ monitoringSymbolsWithinSlot = (uss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (uss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
+ for (int i = 0; i < sps; i++)
+ if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
+ rel15->coreset.StartSymbolIndex = i;
+ break;
+ }
+ fill_dci_search_candidates(uss, rel15);
+ }
+
+ // Scrambling RNTI
+ if (coreset->pdcch_DMRS_ScramblingID) {
+ rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID;
+ rel15->coreset.scrambling_rnti = mac->t_crnti;
+ } else {
+ rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId;
+ if(mac->ra_state == WAIT_RAR)
+ rel15->coreset.scrambling_rnti = 0;
else
- rel15->coreset.pdcch_dmrs_scrambling_id = *mac->scc->physCellId;
- fill_dci_search_candidates(mac->SSpace[0][0][ss_id],rel15);
- rel15->dci_format = NR_DL_DCI_FORMAT_1_0;
- rel15->dci_length = nr_dci_size(rel15->dci_format,NR_RNTI_C,rel15->BWPSize);
+ rel15->coreset.scrambling_rnti = rel15->rnti;
+ }
+
+ if (add_dci){
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
dl_config->number_pdus = dl_config->number_pdus + 1;
}
}
}
-
-
-
-
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index a962e799ed..0da02bd7d1 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -31,28 +31,38 @@
*/
-/* MAC related headers */
-#include "mac_proto.h"
+#include
+#include
+
+/* exe */
+#include "executables/nr-softmodem.h"
+
+/* RRC*/
+#include "RRC/NR_UE/rrc_proto.h"
+#include "NR_RACH-ConfigCommon.h"
+#include "NR_RACH-ConfigGeneric.h"
+#include "NR_FrequencyInfoDL.h"
+#include "NR_PDCCH-ConfigCommon.h"
+
+/* MAC */
#include "mac_defs.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
-#include "mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac.h"
+#include "NR_MAC_UE/mac_proto.h"
+#include "NR_MAC_UE/mac_extern.h"
#include "common/utils/nr/nr_common.h"
-//#include "LAYER2/MAC/mac_vars.h" // TODO Note that mac_vars.h is not NR specific and this should be updated
- // also, the use of the same should be updated in nr-softmodem and nr-uesoftmodem
-
-/* PHY UE related headers*/
+/* PHY UE */
#include "SCHED_NR_UE/defs.h"
-
-#include "RRC/NR_UE/rrc_proto.h"
-#include "assertions.h"
#include "PHY/defs_nr_UE.h"
/*Openair Packet Tracer */
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "executables/softmodem-common.h"
-/* log utils */
+
+/* utils */
+#include "assertions.h"
+
#include "common/utils/LOG/log.h"
#include "SIMULATION/TOOLS/sim.h" // for taus
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h"
@@ -60,11 +70,12 @@
#include
#include
-//int mbms_rab_id = 2047;
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
#define DEBUG_EXTRACT_DCI 1
+extern const uint16_t nr_slots_per_frame[5];
+
extern void mac_rlc_data_ind (
const module_id_t module_idP,
const rnti_t rntiP,
@@ -641,100 +652,482 @@ uint32_t get_ssb_frame(uint32_t test){
// 1. TODO: Call RRC for link status return to PHY
// 2. TODO: Perform SR/BSR procedures for scheduling feedback
// 3. TODO: Perform PHR procedures
-NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id,
- const uint8_t gNB_index,
- const int cc_id,
- const frame_t rx_frame,
- const slot_t rx_slot,
- const int32_t ssb_index,
- const frame_t tx_frame,
- const slot_t tx_slot ){
+NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info){
uint32_t search_space_mask = 0;
- NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
- fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
-
- // check type0 from 38.213 13 if we have no CellGroupConfig
- if ( mac->scd == NULL) {
- if( ssb_index != -1){
-
- if(mac->type0_pdcch_ss_mux_pattern == 1){
- // 38.213 chapter 13
- if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
- search_space_mask = search_space_mask | type0_pdcch;
- mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
- }
- if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
- search_space_mask = search_space_mask | type0_pdcch;
- mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
- }
+ if (dl_info){
+
+ module_id_t mod_id = dl_info->module_id;
+ uint32_t gNB_index = dl_info->gNB_index;
+ int cc_id = dl_info->cc_id;
+ frame_t rx_frame = dl_info->frame;
+ slot_t rx_slot = dl_info->slot;
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+
+ fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
+ nr_scheduled_response_t scheduled_response;
+ nr_dcireq_t dcireq;
+
+ // check type0 from 38.213 13 if we have no CellGroupConfig
+ // TODO: implementation to be completed
+ if (mac->scd == NULL) {
+ if(dl_info->ssb_index != -1){
+
+ if(mac->type0_pdcch_ss_mux_pattern == 1){
+ // 38.213 chapter 13
+ if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
+ search_space_mask = search_space_mask | type0_pdcch;
+ mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
+ }
+ if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){
+ search_space_mask = search_space_mask | type0_pdcch;
+ mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
+ }
+ }
+ if(mac->type0_pdcch_ss_mux_pattern == 2){
+ // 38.213 Table 13-13, 13-14
+ if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
+ search_space_mask = search_space_mask | type0_pdcch;
+ mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
+ }
+ }
+ if(mac->type0_pdcch_ss_mux_pattern == 3){
+ // 38.213 Table 13-15
+ if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
+ search_space_mask = search_space_mask | type0_pdcch;
+ mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
+ }
+ }
+ } // ssb_index != -1
+
+ // Type0 PDCCH search space
+ if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){
+ mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1;
+
+ dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config;
+ dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
+
+ /*
+ dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set
+ dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set
+
+ LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n",
+ dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti,
+ dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP);
+ */
+ dl_config->number_pdus = dl_config->number_pdus + 1;
+ mac->scheduled_response.dl_config = dl_config;
}
- if(mac->type0_pdcch_ss_mux_pattern == 2){
- // 38.213 Table 13-13, 13-14
- if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
- search_space_mask = search_space_mask | type0_pdcch;
- mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
- }
+ } else { // we have an scd
+
+ dcireq.module_id = mod_id;
+ dcireq.gNB_index = gNB_index;
+ dcireq.cc_id = cc_id;
+ dcireq.frame = rx_frame;
+ dcireq.slot = rx_slot;
+ nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
+
+ // we should have received a DL DCI here, so configure DL accordingly
+ scheduled_response.dl_config = &dcireq.dl_config_req;
+ scheduled_response.ul_config = NULL;
+ scheduled_response.tx_request = NULL;
+ scheduled_response.module_id = mod_id;
+ scheduled_response.CC_id = cc_id;
+ scheduled_response.frame = rx_frame;
+ scheduled_response.slot = rx_slot;
+
+ if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
+ mac->if_module->scheduled_response(&scheduled_response);
}
- if(mac->type0_pdcch_ss_mux_pattern == 3){
- // 38.213 Table 13-15
- if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){
- search_space_mask = search_space_mask | type0_pdcch;
- mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration;
- }
- }
- } // ssb_index != -1
-
- // Type0 PDCCH search space
- if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){
- mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1;
-
- dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config;
- dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
-
+
/*
- dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set
- dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set
-
- LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n",
- dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti,
- dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP);
- */
- dl_config->number_pdus = dl_config->number_pdus + 1;
+ if(search_space_mask & type0a_pdcch){
+ }
+
+ if(search_space_mask & type1_pdcch){
+ }
+
+ if(search_space_mask & type2_pdcch){
+ }
+
+ if(search_space_mask & type3_pdcch){
+ }
+ */
}
+ } else if (ul_info && ul_info->slot_tx == 8) {
+ module_id_t mod_id = ul_info->module_id;
+ uint32_t gNB_index = ul_info->gNB_index;
+ int cc_id = ul_info->cc_id;
+ frame_t rx_frame = ul_info->frame_rx;
+ slot_t rx_slot = ul_info->slot_rx;
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+
+ // program PUSCH. this should actually be done upon reception of an UL DCI
+ nr_dcireq_t dcireq;
+ nr_scheduled_response_t scheduled_response;
+
+ //--------------------------Temporary configuration-----------------------------//
+ uint16_t rnti = 0x1234;
+ uint32_t rb_size = 50;
+ uint32_t rb_start = 0;
+ uint8_t nr_of_symbols = 12;
+ uint8_t start_symbol_index = 2;
+ uint8_t nrOfLayers = 1;
+ uint8_t mcs_index = 9;
+ uint8_t mcs_table = 0;
+ uint8_t harq_process_id = 0;
+ uint8_t rv_index = 0;
+ uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
+ uint8_t dmrs_config_type = 0;
+ uint8_t ptrs_mcs1 = 2;
+ uint8_t ptrs_mcs2 = 4;
+ uint8_t ptrs_mcs3 = 10;
+ uint16_t n_rb0 = 25;
+ uint16_t n_rb1 = 75;
+ uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
+ uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
+ uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
+ //------------------------------------------------------------------------------//
+
+ dcireq.module_id = mod_id;
+ dcireq.gNB_index = gNB_index;
+ dcireq.cc_id = cc_id;
+ dcireq.frame = rx_frame;
+ dcireq.slot = rx_slot;
+
+ scheduled_response.dl_config = NULL;
+ scheduled_response.ul_config = &dcireq.ul_config_req;
+ scheduled_response.tx_request = NULL;
+ scheduled_response.module_id = mod_id;
+ scheduled_response.CC_id = cc_id;
+ scheduled_response.frame = rx_frame;
+ scheduled_response.slot = rx_slot;
+
+ scheduled_response.ul_config->slot = ul_info->slot_tx;
+ scheduled_response.ul_config->number_pdus = 1;
+ scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
+
+ if (1 << ptrs_time_density >= nr_of_symbols) {
+ scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
+ }
+
+ if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
+ mac->if_module->scheduled_response(&scheduled_response);
+ }
+
+ // TODO: expand
+ // Note: Contention resolution is currently not active
+ if (mac->RA_contention_resolution_timer_active == 1)
+ ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
}
- else { // get PDCCH configuration(s) from SCGConfig
-
-
-
-
- // get Coreset and SearchSpace Information from spCellConfigDedicated
-
-
-
- /*
- if(search_space_mask & type0a_pdcch){
- }
-
- if(search_space_mask & type1_pdcch){
- }
-
- if(search_space_mask & type2_pdcch){
- }
-
- if(search_space_mask & type3_pdcch){
- }
- */
- }
-
-
- mac->scheduled_response.dl_config = dl_config;
-
return UE_CONNECTION_OK;
}
+// Notes:
+// - Type1-PDCCH CSS configuration from ra-SearchSpace.
+// - Msg2 is scheduled in the mixed slot or in the last dl slot if they are allowed by the Type 1 Common Search Space configuration
+// todo:
+// - if Type1-PDCCH CSS is not configured in RRC message (Coreset and SearchSpace), UE searches in Type 0 PDCCH CSS.
+void nr_ue_msg2_scheduler(module_id_t mod_id,
+ uint16_t rach_frame,
+ uint16_t rach_slot,
+ uint16_t *msg2_frame,
+ uint16_t *msg2_slot){
+
+ uint8_t bwp_id = 1;
+ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+ NR_ServingCellConfig_t *scd = mac->scd;
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_BWP_Downlink_t *bwp = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1];
+ NR_SearchSpace_t *ss;
+ struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ uint8_t mu = *scc->ssbSubcarrierSpacing;
+ uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow;
+ uint8_t slot_window, slot_limit, frame_limit;
+ uint16_t start_next_period, monitoring_slot_period, monitoring_offset;
+
+ // number of mixed slot or of last dl slot if there is no mixed slot
+ uint16_t last_dl_slot_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
+ uint16_t nr_dl_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols;
+ uint16_t nr_ul_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
+
+ // lenght of tdd period in slots
+ uint16_t tdd_period_slot = last_dl_slot_period + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+
+ AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH common SearchSpace list has 0 elements\n");
+
+ LOG_D(MAC, "Frame %d, Slot %d: Scheduling Msg2 reception \n", rach_frame, rach_slot);
+
+ // Common searchspace list
+ for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
+ ss = commonSearchSpaceList->list.array[i];
+ if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
+ // retrieving ra pdcch monitoring period and offset
+ find_monitoring_periodicity_offset_common(ss, &monitoring_slot_period, &monitoring_offset);
+ }
+
+ if (nr_dl_symbols == 0)
+ last_dl_slot_period--;
+ if ((nr_dl_symbols > 0) || (nr_ul_symbols > 0))
+ tdd_period_slot++;
+
+ // computing start of next period
+ start_next_period = (rach_slot - (rach_slot % tdd_period_slot) + tdd_period_slot) % nr_slots_per_frame[mu];
+ *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
+ *msg2_frame = (*msg2_slot > rach_slot) ? rach_frame : (rach_frame +1);
+
+ switch(response_window){
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
+ slot_window = 1;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
+ slot_window = 2;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
+ slot_window = 4;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
+ slot_window = 8;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
+ slot_window = 10;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
+ slot_window = 20;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
+ slot_window = 40;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
+ slot_window = 80;
+ break;
+ default:
+ AssertFatal(1==0,"Invalid response window value %d\n",response_window);
+ }
+ AssertFatal(slot_window<=nr_slots_per_frame[mu], "Msg2 response window needs to be lower or equal to 10ms");
+
+ // slot and frame limit to transmit msg2 according to response window
+ slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
+ frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
+
+ // go to previous slot if the current scheduled slot is beyond the response window
+ // and if the slot is not among the PDCCH monitored ones (38.213 10.1)
+ while ((*msg2_slot > slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu] + *msg2_slot - monitoring_offset) % monitoring_slot_period != 0)) {
+ if((*msg2_slot % tdd_period_slot) > 0)
+ (*msg2_slot)--;
+ else
+ AssertFatal(1 == 0, "No available DL slot to schedule reception of msg2 has been found");
+ }
+ LOG_D(MAC, "Scheduled Msg2 reception in Frame %d, Slot %d: \n", *msg2_frame, *msg2_slot);
+}
+
+// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
+// It fills the PRACH PDU per each FD occasion.
+// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
+// - todo:
+// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config
+void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
+
+ uint8_t config_index, mu, N_dur, N_t_slot, start_symbol;
+ uint16_t format, format0, format1, ncs;
+ int msg1_FDM, is_nr_prach_slot, fdm;
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
+
+ fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
+ fapi_nr_ul_config_prach_pdu *prach_config_pdu;
+ fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
+ fapi_nr_prach_config_t *prach_config = &cfg->prach_config;
+
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+ NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
+ NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
+ config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
+
+ mac->RA_offset = 2; // to compensate the rx frame offset at the gNB
+
+ if (is_nr_UL_slot(scc, slotP)) {
+
+ if (setup->msg1_SubcarrierSpacing)
+ mu = *setup->msg1_SubcarrierSpacing;
+ else
+ mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+ is_nr_prach_slot = get_nr_prach_info_from_index(config_index,
+ (int)frameP,
+ (int)slotP,
+ frequencyInfoDL->absoluteFrequencyPointA,
+ mu,
+ cfg->cell_config.frame_duplex_type,
+ &format,
+ &start_symbol,
+ &N_t_slot,
+ &N_dur);
+
+ if (is_nr_prach_slot && mac->ra_state == RA_UE_IDLE) {
+
+ mac->generate_nr_prach = 1;
+
+ fdm = rach_ConfigGeneric->msg1_FDM;
+
+ switch (fdm){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ msg1_FDM = 1 << fdm;
+ break;
+ default:
+ AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", fdm);
+ }
+
+ format0 = format & 0xff; // single PRACH format
+ format1 = (format >> 8) & 0xff; // dual PRACH format
+
+ ul_config->sfn = frameP;
+ ul_config->slot = slotP;
+
+ for (int n = 0; n < msg1_FDM; n++) { // one structure per frequency domain occasion
+
+ ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH;
+ prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
+ memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
+ ul_config->number_pdus += 1;
+
+ ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
+
+ // filling PRACH PDU for FAPI config request
+ prach_config_pdu->phys_cell_id = *scc->physCellId;
+ prach_config_pdu->num_prach_ocas = N_t_slot;
+ prach_config_pdu->prach_start_symbol = start_symbol;
+ prach_config_pdu->num_ra = n;
+ prach_config_pdu->num_cs = ncs;
+ prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[n].prach_root_sequence_index;
+ prach_config_pdu->restricted_set = prach_config->restricted_set_config;
+ prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[n].k1;
+
+ if (format1 != 0xff) {
+ switch(format0) { // dual PRACH format
+ case 0xa1:
+ prach_config_pdu->prach_format = 9;
+ break;
+ case 0xa2:
+ prach_config_pdu->prach_format = 10;
+ break;
+ case 0xa3:
+ prach_config_pdu->prach_format = 11;
+ break;
+ default:
+ AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
+ }
+ } else {
+ switch(format0) { // single PRACH format
+ case 0xa1:
+ prach_config_pdu->prach_format = 0;
+ break;
+ case 0xa2:
+ prach_config_pdu->prach_format = 1;
+ break;
+ case 0xa3:
+ prach_config_pdu->prach_format = 2;
+ break;
+ case 0xb1:
+ prach_config_pdu->prach_format = 3;
+ break;
+ case 0xb2:
+ prach_config_pdu->prach_format = 4;
+ break;
+ case 0xb3:
+ prach_config_pdu->prach_format = 5;
+ break;
+ case 0xb4:
+ prach_config_pdu->prach_format = 6;
+ break;
+ case 0xc0:
+ prach_config_pdu->prach_format = 7;
+ break;
+ case 0xc2:
+ prach_config_pdu->prach_format = 8;
+ break;
+ case 0:
+ // long formats are handled @ PHY
+ break;
+ case 1:
+ // long formats are handled @ PHY
+ break;
+ case 2:
+ // long formats are handled @ PHY
+ break;
+ case 3:
+ // long formats are handled @ PHY
+ break;
+ default:
+ AssertFatal(1 == 0, "Invalid PRACH format");
+ }
+ }
+ }
+ } else {
+ mac->generate_nr_prach = 0;
+ }
+ mac->scheduled_response.ul_config = ul_config;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
+////////////////////////////////////////////////////////////////////////////
+// Handling contention resolution timer
+// WIP todo:
+// - beam failure recovery
+// - RA completed
+
+void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame){
+
+ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
+ NR_ServingCellConfigCommon_t *scc = mac->scc;
+ NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+
+ if (mac->RA_contention_resolution_timer_active == 1) {
+ if (nr_rach_ConfigCommon){
+ LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n",
+ tx_frame,
+ mac->RA_contention_resolution_cnt,
+ ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3));
+ mac->RA_contention_resolution_cnt++;
+
+ if (mac->RA_contention_resolution_cnt == ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) {
+ mac->t_crnti = 0;
+ mac->RA_active = 0;
+ mac->RA_contention_resolution_timer_active = 0;
+ // Signal PHY to quit RA procedure
+ LOG_E(MAC, "[UE %u] [RAPROC] Contention resolution timer expired, RA failed, discarded TC-RNTI\n", module_id);
+ nr_ra_failed(module_id, cc_id, gNB_index);
+ }
+ }
+ }
+}
+
#if 0
uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue,
uint8_t slot,
@@ -1905,8 +2298,8 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,&dci_pdu_rel15);
- nr_ue_process_dci(module_id, cc_id, gNB_index, &dci_pdu_rel15, dci->rnti, dci->dci_format);
- return 0;
+
+ return (nr_ue_process_dci(module_id, cc_id, gNB_index, &dci_pdu_rel15, dci->rnti, dci->dci_format));
}
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
@@ -2400,7 +2793,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI)*/
dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = dci->pdsch_to_harq_feedback_time_ind;
- LOG_D(MAC,"(nr_ue_procedures.c) rnti=%d dl_config->number_pdus=%d\n",
+ LOG_D(MAC,"(nr_ue_procedures.c) rnti = %x dl_config->number_pdus = %d\n",
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti,
dl_config->number_pdus);
LOG_D(MAC,"(nr_ue_procedures.c) frequency_domain_resource_assignment=%d \t number_rbs=%d \t start_rb=%d\n",
@@ -2423,7 +2816,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr
dlsch_config_pdu_1_0->pucch_resource_id,
dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind);
- dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
+ if (mac->ra_rnti == rnti)
+ dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
+ else
+ dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
+
// dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP;
LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
@@ -2765,7 +3162,9 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu);
#endif
break;
-
+
+ mac->rnti_type = rnti_type;
+
case NR_RNTI_C:
// indicating a DL DCI format 1bit
@@ -3066,6 +3465,7 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
uint8_t *pdu_ptr = pduP, rx_lcid, done = 0;
int pdu_len = mac_pdu_len;
uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len;
+ NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
//NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP);
//uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon;
@@ -3226,8 +3626,34 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
break;
case DL_SCH_LCID_CON_RES_ID:
// 38.321 Ch6.1.3.3
+ // WIP todo: handle CCCH_pdu
mac_ce_len = 6;
+
+ LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pdu_ptr[0], pdu_ptr[1], pdu_ptr[2], pdu_ptr[3], pdu_ptr[4], pdu_ptr[5]);
+ if (mac->RA_active == 1) {
+ LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP);
+ mac->RA_active = 0;
+ // // check if RA procedure has finished completely (no contention)
+ // tx_sdu = &mac->CCCH_pdu.payload[3];
+ // //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits)
+ // // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or // SCH_SUBHEADER_SHORT)
+ // for (i = 0; i < 6; i++)
+ // if (tx_sdu[i] != payload_ptr[i]) {
+ // LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP);
+ // nr_ra_failed(module_idP, CC_id, eNB_index);
+ // mac->RA_contention_resolution_timer_active = 0;
+ // return;
+ // }
+ LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Cleared contention resolution timer. Set C-RNTI to TC-RNTI\n",
+ module_idP,
+ frameP);
+ mac->RA_contention_resolution_timer_active = 0;
+ nr_ra_succeeded(module_idP, CC_id, gNB_index);
+ mac->crnti = mac->t_crnti;
+ mac->t_crnti = 0;
+ mac->ra_state = RA_SUCCEEDED;
+ }
break;
case DL_SCH_LCID_PADDING:
done = 1;
@@ -3293,71 +3719,181 @@ void nr_ue_process_mac_pdu(module_id_t module_idP,
}
}
-//---------------------------------------------------------------------------------
+////////////////////////////////////////////////////////
+/////* ULSCH MAC PDU generation (6.1.2 TS 38.321) */////
+////////////////////////////////////////////////////////
+uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
+ uint8_t *pdu,
+ uint8_t num_sdus,
+ uint16_t *sdu_lengths,
+ uint8_t *sdu_lcids,
+ uint8_t power_headroom,
+ uint16_t crnti,
+ uint16_t truncated_bsr,
+ uint16_t short_bsr,
+ uint16_t long_bsr,
+ unsigned short post_padding,
+ uint16_t buflen) {
-uint16_t
-nr_generate_ulsch_pdu(uint8_t *mac_pdu,
- uint8_t *sdus_payload,
- uint8_t num_sdus,
- uint16_t *sdu_lengths,
- uint8_t *sdu_lcids,
- uint16_t *crnti,
- uint16_t buflen) {
+ NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu;
+ unsigned char last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0;
+ int mac_ce_size;
+ uint16_t offset = 0;
- NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
- unsigned char * ulsch_buffer_ptr = sdus_payload;
- uint8_t last_size=0;
- uint16_t sdu_length_total=0;
- int i;
- int offset=0;
+ LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus);
- // 2) Generation of ULSCH MAC SDU subheaders
- for (i = 0; i < num_sdus; i++) {
- LOG_D(MAC, "[gNB] Generate ULSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]);
+ #ifdef DEBUG_HEADER_PARSING
- if (sdu_lengths[i] < 128) {
- ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
- ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
- ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
- ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
- last_size = 2;
- } else {
- ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
- ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
- ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
- ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
- ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
- last_size = 3;
- }
+ for (i = 0; i < num_sdus; i++)
+ LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]);
- mac_pdu_ptr += last_size;
+ #endif
- // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in
- memcpy((void *) mac_pdu_ptr, (void *) ulsch_buffer_ptr, sdu_lengths[i]);
- ulsch_buffer_ptr+= sdu_lengths[i];
- sdu_length_total+= sdu_lengths[i];
- mac_pdu_ptr += sdu_lengths[i];
- }
+ // Generating UL MAC subPDUs including MAC SDU and subheader
- offset = ((unsigned char *) mac_pdu_ptr - mac_pdu);
+ for (i = 0; i < num_sdus; i++) {
+ LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus);
- // 4) Compute final offset for padding
- uint16_t padding_bytes = buflen - offset;
- LOG_D(MAC, "Number of padding bytes: %d \n", padding_bytes);
- if (padding_bytes > 0) {
- ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
- ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
- mac_pdu_ptr++;
+ if (sdu_lcids[i] != UL_SCH_LCID_CCCH){
+ if (sdu_lengths[i] < 128) {
+ ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
+ ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
+ ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i];
+ ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i];
+ last_size = 2;
+ } else {
+ ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0;
+ ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1;
+ ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i];
+ ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
+ ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff;
+ last_size = 3;
+ }
+ } else { // UL CCCH SDU
+ mac_pdu_ptr->R = 0;
+ mac_pdu_ptr->LCID = sdu_lcids[i];
+ }
- } else {
- // no MAC subPDU with padding
- }
+ mac_pdu_ptr += last_size;
+
+ // cycle through SDUs, compute each relevant and place ulsch_buffer in
+ memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]);
+ sdus_payload += sdu_lengths[i];
+ mac_pdu_ptr += sdu_lengths[i];
+ }
+
+ // Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader)
+
+ ce_ptr = &mac_header_control_elements[0];
+
+ if (power_headroom) {
+ // MAC CE fixed subheader
+ mac_pdu_ptr->R = 0;
+ mac_pdu_ptr->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR;
+ mac_pdu_ptr++;
+
+ // PHR MAC CE (1 octet)
+ ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom;
+ ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0;
+ ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo
+ ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0;
+
+ mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE);
+
+ // Copying bytes for PHR MAC CEs to the mac pdu pointer
+ memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
+ ce_ptr += mac_ce_size;
+ mac_pdu_ptr += (unsigned char) mac_ce_size;
+ }
+
+ if (crnti) {
+ // MAC CE fixed subheader
+ mac_pdu_ptr->R = 0;
+ mac_pdu_ptr->LCID = CRNTI;
+ mac_pdu_ptr++;
+
+ // C-RNTI MAC CE (2 octets)
+ * (uint16_t *) ce_ptr = crnti;
+ mac_ce_size = sizeof(uint16_t);
+
+ // Copying bytes for CRNTI MAC CE to the mac pdu pointer
+ memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
+ ce_ptr += mac_ce_size;
+ mac_pdu_ptr += (unsigned char) mac_ce_size;
+ }
+
+ if (truncated_bsr) {
+ // MAC CE fixed subheader
+ mac_pdu_ptr->R = 0;
+ mac_pdu_ptr->LCID = UL_SCH_LCID_S_TRUNCATED_BSR;
+ mac_pdu_ptr++;
+
+ // Short truncated BSR MAC CE (1 octet)
+ ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr;
+ ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo
+ mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED);
+
+ bsr = 1 ;
+ } else if (short_bsr) {
+ // MAC CE fixed subheader
+ mac_pdu_ptr->R = 0;
+ mac_pdu_ptr->LCID = UL_SCH_LCID_S_BSR;
+ mac_pdu_ptr++;
+
+ // Short truncated BSR MAC CE (1 octet)
+ ((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr;
+ ((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo
+ mac_ce_size = sizeof(NR_BSR_SHORT);
+
+ bsr = 1 ;
+ } else if (long_bsr) {
+ // MAC CE variable subheader
+ // todo ch 6.1.3.1. TS 38.321
+ // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0;
+ // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0;
+ // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR;
+ // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0;
+ // last_size = 2;
+ // mac_pdu_ptr += last_size;
+
+ // Short truncated BSR MAC CE (1 octet)
+ // ((NR_BSR_LONG *) ce_ptr)->Buffer_size0 = short_bsr;
+ // ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0;
+ // mac_ce_size = sizeof(NR_BSR_LONG); // size is variable
+ }
+
+ if (bsr){
+ // Copying bytes for BSR MAC CE to the mac pdu pointer
+ memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
+ ce_ptr += mac_ce_size;
+ mac_pdu_ptr += (unsigned char) mac_ce_size;
+ }
+
+ // compute offset before adding padding (if necessary)
+ offset = ((unsigned char *) mac_pdu_ptr - pdu);
+ uint16_t padding_bytes = 0;
+
+ if(buflen > 0) // If the buflen is provided
+ padding_bytes = buflen - offset;
+
+ // Compute final offset for padding
+ if (post_padding > 0 || padding_bytes>0) {
+ ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
+ ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING;
+ mac_pdu_ptr++;
+ } else {
+ // no MAC subPDU with padding
+ }
+
+ // compute final offset
+ offset = ((unsigned char *) mac_pdu_ptr - pdu);
+
+ //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - pdu));
return offset;
}
-
uint8_t
nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
sub_frame_t subframe, uint8_t eNB_index,
@@ -3430,13 +3966,6 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
sdu_length_total += sdu_lengths[num_sdus];
sdu_lcids[num_sdus] = lcid;
-
- //Update total MAC Header size for RLC PDUs
- /*if(sdu_lengths[num_sdus]<128)
- total_rlc_pdu_header_len += 2;
- else
- total_rlc_pdu_header_len += 3;*/
-
total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last;
//Update number of SDU
@@ -3461,13 +3990,18 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
// Generate ULSCH PDU
if (num_sdus>0) {
- payload_offset = nr_generate_ulsch_pdu(ulsch_buffer, // mac header
- ulsch_sdus,
+ payload_offset = nr_generate_ulsch_pdu(ulsch_sdus,
+ ulsch_buffer, // mac header
num_sdus, // num sdus
sdu_lengths, // sdu length
sdu_lcids, // sdu lcid
- NULL, // crnti
- buflen); // long_bsr
+ 0, // power_headroom
+ 0, // crnti
+ 0, // truncated_bsr
+ 0, // short_bsr
+ 0, // long_bsr
+ 0, // post_padding
+ buflen); // TBS in bytes
}
else
return 0;
diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c
new file mode 100644
index 0000000000..bfd2d3dbeb
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c
@@ -0,0 +1,208 @@
+/*
+ * 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 rar_tools_nrUE.c
+ * \brief RA tools for NR UE
+ * \author Guido Casati
+ * \date 2019
+ * \version 1.0
+ * @ingroup _mac
+
+ */
+
+/* Sim */
+#include "SIMULATION/TOOLS/sim.h"
+
+/* Utils */
+#include "common/utils/LOG/log.h"
+#include "OCG.h"
+#include "OCG_extern.h"
+#include "UTIL/OPT/opt.h"
+
+/* Common */
+#include "common/ran_context.h"
+
+/* MAC */
+#include "NR_MAC_UE/mac.h"
+#include "NR_MAC_UE/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
+
+#define DEBUG_RAR
+
+// table 7.2-1 TS 38.321
+uint16_t table_7_2_1[16] = {
+ 5, // row index 0
+ 10, // row index 1
+ 20, // row index 2
+ 30, // row index 3
+ 40, // row index 4
+ 60, // row index 5
+ 80, // row index 6
+ 120, // row index 7
+ 160, // row index 8
+ 240, // row index 9
+ 320, // row index 10
+ 480, // row index 11
+ 960, // row index 12
+ 1920, // row index 13
+};
+
+/////////////////////////////////////
+// Random Access Response PDU //
+// TS 38.213 ch 8.2 //
+// TS 38.321 ch 6.2.3 //
+/////////////////////////////////////
+//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
+//| E | T | R A P I D |//
+//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |//
+//| R | T A |//
+//| T A | UL grant |//
+//| UL grant |//
+//| UL grant |//
+//| UL grant |//
+//| T C - R N T I |//
+//| T C - R N T I |//
+/////////////////////////////////////
+// UL grant (27 bits) //
+/////////////////////////////////////
+//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
+//|-------------------|FHF|F_alloc|//
+//| Freq allocation |//
+//| F_alloc |Time allocation|//
+//| MCS | TPC |CSI|//
+/////////////////////////////////////
+// WIP todo:
+// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213
+// - apply tpc command, csi req, mcs
+uint16_t nr_ue_process_rar(module_id_t mod_id,
+ int CC_id,
+ frame_t frameP,
+ uint8_t * dlsch_buffer,
+ rnti_t * t_crnti,
+ uint8_t preamble_index,
+ uint8_t * selected_rar_buffer){
+
+ NR_UE_MAC_INST_t *ue_mac = get_mac_inst(mod_id);
+ NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer
+ NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer
+ uint8_t n_subPDUs = 0; // number of RAR payloads
+ uint8_t n_subheaders = 0; // number of MAC RAR subheaders
+ //uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
+ unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req;
+ uint16_t ta_command = 0, msg3_f_alloc, bwp_size;
+ int f_alloc, mask;
+
+ AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n");
+
+ while (1) {
+ n_subheaders++;
+ if (rarh->T == 1) {
+ n_subPDUs++;
+ LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id);
+ } else {
+ n_subPDUs++;
+ ue_mac->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI];
+ ue_mac->RA_BI_found = 1;
+ LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ue_mac->RA_backoff_indicator);
+ }
+ if (rarh->RAPID == preamble_index) {
+ LOG_D(PHY, "[UE %d][RAPROC] Found RAR with the intended RAPID %d\n", mod_id, rarh->RAPID);
+ rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
+ ue_mac->RA_RAPID_found = 1;
+ break;
+ }
+ if (rarh->E == 0) {
+ LOG_I(PHY, "No RAR found with the intended RAPID. \n");
+ break;
+ } else {
+ rarh += sizeof(NR_MAC_RAR) + 1;
+ }
+ };
+
+ LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_subheaders, n_subPDUs);
+
+ // LOG_I(MAC, "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
+ // mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
+
+ if (ue_mac->RA_RAPID_found) {
+ // TC-RNTI
+ *t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
+ ue_mac->t_crnti = *t_crnti;
+ ue_mac->rnti_type = NR_RNTI_TC;
+ // TA command
+ ta_command = rar->TA2 + (rar->TA1 << 5);
+ // CSI
+ csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
+ // TPC
+ tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
+ switch (tpc_command){
+ case 0:
+ ue_mac->Msg3_TPC = -6;
+ break;
+ case 1:
+ ue_mac->Msg3_TPC = -4;
+ break;
+ case 2:
+ ue_mac->Msg3_TPC = -2;
+ break;
+ case 3:
+ ue_mac->Msg3_TPC = 0;
+ break;
+ case 4:
+ ue_mac->Msg3_TPC = 2;
+ break;
+ case 5:
+ ue_mac->Msg3_TPC = 4;
+ break;
+ case 6:
+ ue_mac->Msg3_TPC = 6;
+ break;
+ case 7:
+ ue_mac->Msg3_TPC = 8;
+ break;
+ }
+ //MCS
+ mcs = (unsigned char) (rar->UL_GRANT_4 >> 4);
+ // time and frequency alloc
+ bwp_size = NRRIV2BW(ue_mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
+ msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07);
+ msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
+
+ if (bwp_size < 180)
+ mask = (1 << ((int) ceil(log2((bwp_size*(bwp_size+1))>>1)))) - 1;
+ else
+ mask = (1 << (28 - (int)(ceil(log2((bwp_size*(bwp_size+1))>>1))))) - 1;
+
+ f_alloc = msg3_f_alloc & mask;
+
+ // frequency hopping flag
+ freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
+ } else {
+ ue_mac->t_crnti = 0;
+ ta_command = (0xffff);
+ }
+
+ // move the selected RAR to the front of the RA_PDSCH buffer
+ memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1);
+ memcpy((void *) (selected_rar_buffer + 1), (void *) rar, sizeof(NR_MAC_RAR));
+
+ return ta_command;
+}
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index b5fdea6760..af75e6afff 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -44,7 +44,7 @@
#include "SCHED_NR/phy_frame_config_nr.h"
#include "NR_MIB.h"
-#include "nr_mac_common.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
extern RAN_CONTEXT_t RC;
//extern int l2_init_gNB(void);
@@ -121,13 +121,23 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
}
}
+ lte_frame_type_t frame_type;
+ uint16_t band;
+ int32_t offset;
+
+ get_band((cfg->carrier_config.dl_frequency.value)*1000,
+ &band,
+ &offset,
+ &frame_type);
+
+ RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
// Cell configuration
cfg->cell_config.phy_cell_id.value = *scc->physCellId;
cfg->cell_config.phy_cell_id.tl.tag = NFAPI_NR_CONFIG_PHY_CELL_ID_TAG;
cfg->num_tlv++;
- cfg->cell_config.frame_duplex_type.value = 1;
+ cfg->cell_config.frame_duplex_type.value = frame_type;
cfg->cell_config.frame_duplex_type.tl.tag = NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG;
cfg->num_tlv++;
@@ -143,7 +153,11 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
// PRACH configuration
- cfg->prach_config.prach_sequence_length.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present;
+ uint8_t nb_preambles = 64;
+ if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
+ nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
+
+ cfg->prach_config.prach_sequence_length.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1;
cfg->prach_config.prach_sequence_length.tl.tag = NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG;
cfg->num_tlv++;
@@ -153,7 +167,6 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.prach_sub_c_spacing.value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
cfg->prach_config.prach_sub_c_spacing.tl.tag = NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG;
cfg->num_tlv++;
-
cfg->prach_config.restricted_set_config.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
cfg->prach_config.restricted_set_config.tl.tag = NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG;
cfg->num_tlv++;
@@ -192,13 +205,17 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.tl.tag = NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG;
cfg->num_tlv++;
+ cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,
+ nb_preambles, frame_type);
+ cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.tl.tag = NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG;
+ cfg->num_tlv++;
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = ???
}
- cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
+ cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
cfg->prach_config.ssb_per_rach.tl.tag = NFAPI_NR_CONFIG_SSB_PER_RACH_TAG;
cfg->num_tlv++;
-
+
// SSB Table Configuration
int scs_scaling = 1<<(cfg->ssb_config.scs_common.value);
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index e3d55711a7..9642d6db80 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -33,9 +33,9 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
@@ -61,8 +61,6 @@
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
-uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
-
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
int CC_idP,
frame_t frameP,
@@ -259,18 +257,6 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
}
*/
-/*
-void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
-
- gNB_MAC_INST *gNB = RC.nrmac[module_idP];
-
- // schedule PRACH for iniital BWP
-
- if (is_initialBWP_prach_subframe(frameP,subframeP)<0) return;
-
- // fill FAPI
-}
-*/
/*
void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
@@ -408,10 +394,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
-
rnti = 0;//UE_RNTI(module_idP, i);
CC_id = 0;//UE_PCCID(module_idP, i);
-
+
} //END if (UE_list->active[i])
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
*/
@@ -447,6 +432,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
}
+ if (get_softmodem_params()->phy_test == 0)
+ nr_schedule_RA(module_idP, frame_txP, slot_txP);
+
/*
// Allocate CCEs for good after scheduling is done
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
@@ -456,6 +444,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
} //is_nr_DL_slot
if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) {
+
+ if (get_softmodem_params()->phy_test == 0) {
+ schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP);
+ nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP);
+ }
if (get_softmodem_params()->phy_test && slot_rxP==8){
nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index d74df15eac..6ce72059fd 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -19,44 +19,800 @@
* contact@openairinterface.org
*/
-/*! \file gNB_scheduler_RA.c
- * \brief primitives used for random access
- * \author
- * \date
- * \email:
+/*! \file gNB_scheduler_RA.c
+ * \brief primitives used for random access
+ * \author Guido Casati
+ * \date 2019
+ * \email: guido.casati@iis.fraunhofer.de
* \version
*/
-#include nr_mac_gNB.h
+#include "platform_types.h"
-void
-schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
-{
+/* MAC */
+#include "nr_mac_gNB.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
- eNB_MAC_INST *mac = RC.mac[module_idP];
- COMMON_channels_t *cc = mac->common_channels;
- RA_t *ra;
- uint8_t i;
+/* Utils */
+#include "common/utils/LOG/log.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "common/utils/nr/nr_common.h"
+#include "UTIL/OPT/opt.h"
+#include "SIMULATION/TOOLS/sim.h" // for taus
+
+extern RAN_CONTEXT_t RC;
+extern const uint16_t nr_slots_per_frame[5];
+uint8_t DELTA[4]= {2,3,4,6};
+
+void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
+
+ gNB_MAC_INST *gNB = RC.nrmac[module_idP];
+ NR_COMMON_channels_t *cc = gNB->common_channels;
+ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0];
+
+ uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
+ uint8_t mu,N_dur,N_t_slot,start_symbol;
+ uint16_t format;
+
+ if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
+ mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
+ else
+ mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+
+ // prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
+ if ( get_nr_prach_info_from_index(config_index,
+ (int)frameP,
+ (int)slotP,
+ scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
+ mu,
+ cc->frame_type,
+ &format,
+ &start_symbol,
+ &N_t_slot,
+ &N_dur) ) {
+
+ int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM;
+ uint16_t format0 = format&0xff; // first column of format from table
+ uint16_t format1 = (format>>8)&0xff; // second column of format from table
+
+ UL_tti_req->SFN = frameP;
+ UL_tti_req->Slot = slotP;
+ for (int n=0; n<(1<pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
+ UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
+ nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
+ memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
+ UL_tti_req->n_pdus+=1;
+
+ // filling the prach fapi structure
+ prach_pdu->phys_cell_id = *scc->physCellId;
+ prach_pdu->num_prach_ocas = N_t_slot;
+ prach_pdu->prach_start_symbol = start_symbol;
+ prach_pdu->num_ra = n;
+ prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
+ format0,
+ scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
+ // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
+ // We added 9 = A1/B1 10 = A2/B2 11 A3/B3
+ if (format1!=0xff) {
+ switch(format0) {
+ case 0xa1:
+ prach_pdu->prach_format = 9;
+ break;
+ case 0xa2:
+ prach_pdu->prach_format = 10;
+ break;
+ case 0xa3:
+ prach_pdu->prach_format = 11;
+ break;
+ default:
+ AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
+ }
+ }
+ else{
+ switch(format0) {
+ case 0xa1:
+ prach_pdu->prach_format = 0;
+ break;
+ case 0xa2:
+ prach_pdu->prach_format = 1;
+ break;
+ case 0xa3:
+ prach_pdu->prach_format = 2;
+ break;
+ case 0xb1:
+ prach_pdu->prach_format = 3;
+ break;
+ case 0xb2:
+ prach_pdu->prach_format = 4;
+ break;
+ case 0xb3:
+ prach_pdu->prach_format = 5;
+ break;
+ case 0xb4:
+ prach_pdu->prach_format = 6;
+ break;
+ case 0xc0:
+ prach_pdu->prach_format = 7;
+ break;
+ case 0xc2:
+ prach_pdu->prach_format = 8;
+ break;
+ case 0:
+ // long formats are handled @ PHY
+ break;
+ case 1:
+ // long formats are handled @ PHY
+ break;
+ case 2:
+ // long formats are handled @ PHY
+ break;
+ case 3:
+ // long formats are handled @ PHY
+ break;
+ default:
+ AssertFatal(1==0,"Invalid PRACH format");
+ }
+ }
+ }
+ }
+}
+
+
+void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
+ uint16_t *msg2_frame, uint16_t *msg2_slot,
+ NR_ServingCellConfigCommon_t *scc,
+ uint16_t monitoring_slot_period,
+ uint16_t monitoring_offset){
+
+ // preferentially we schedule the msg2 in the mixed slot or in the last dl slot
+ // if they are allowed by search space configuration
+
+ uint8_t mu = *scc->ssbSubcarrierSpacing;
+ uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow;
+ uint8_t slot_window;
+ // number of mixed slot or of last dl slot if there is no mixed slot
+ uint8_t last_dl_slot_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
+ // lenght of tdd period in slots
+ uint8_t tdd_period_slot = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+ if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols == 0)
+ last_dl_slot_period--;
+ if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0))
+ tdd_period_slot++;
+
+ // computing start of next period
+ uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
+ *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
+ *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
+
+ switch(response_window){
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
+ slot_window = 1;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
+ slot_window = 2;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
+ slot_window = 4;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
+ slot_window = 8;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
+ slot_window = 10;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
+ slot_window = 20;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
+ slot_window = 40;
+ break;
+ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
+ slot_window = 80;
+ break;
+ default:
+ AssertFatal(1==0,"Invalid response window value %d\n",response_window);
+ }
+ AssertFatal(slot_window<=nr_slots_per_frame[mu],"Msg2 response window needs to be lower or equal to 10ms");
+
+ // slot and frame limit to transmit msg2 according to response window
+ uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
+ //uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
+
+ // go to previous slot if the current scheduled slot is beyond the response window
+ // and if the slot is not among the PDCCH monitored ones (38.213 10.1)
+ while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
+ if((*msg2_slot%tdd_period_slot) > 0)
+ (*msg2_slot)--;
+ else
+ AssertFatal(1==0,"No available DL slot to schedule msg2 has been found");
+ }
+}
+
+
+void nr_initiate_ra_proc(module_id_t module_idP,
+ int CC_id,
+ frame_t frameP,
+ sub_frame_t slotP,
+ uint16_t preamble_index,
+ uint8_t freq_index,
+ uint8_t symbol,
+ int16_t timing_offset){
+
+ uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL
+ NR_SearchSpace_t *ss;
+
+ // ra_rnti from 5.1.3 in 38.321
+ uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
+
+ uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset;
+ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
+ NR_UE_list_t *UE_list = &nr_mac->UE_list;
+ NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[0];
+ NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
+ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ NR_RA_t *ra = &cc->ra[0];
+
+ // This should be handled differently when we use the initialBWP for RA
+ ra->bwp_id=1;
+ NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
+
+ LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index);
+
+ if (ra->state == RA_IDLE) {
+ int loop = 0;
+ LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
+ ra->state = Msg2;
+ ra->timing_offset = timing_offset;
+ ra->preamble_slot = slotP;
+
+ struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ AssertFatal(commonSearchSpaceList->list.count>0,
+ "common SearchSpace list has 0 elements\n");
+ // Common searchspace list
+ for (int i=0;ilist.count;i++) {
+ ss=commonSearchSpaceList->list.array[i];
+ if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
+ ra->ra_ss=ss;
+ }
+
+ // retrieving ra pdcch monitoring period and offset
+ find_monitoring_periodicity_offset_common(ra->ra_ss,
+ &monitoring_slot_period,
+ &monitoring_offset);
+
+ nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset);
+
+ ra->Msg2_frame = msg2_frame;
+ ra->Msg2_slot = msg2_slot;
+
+ LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
+
+ do {
+ ra->rnti = (taus() % 65518) + 1;
+ loop++;
+ }
+ while (loop != 100 && !(find_nr_UE_id(module_idP, ra->rnti) == -1 && ra->rnti >= 1 && ra->rnti <= 65519));
+ if (loop == 100) {
+ LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
+ abort();
+ }
+
+ ra->RA_rnti = ra_rnti;
+ ra->preamble_index = preamble_index;
+
+
+ LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x\n",
+ module_idP,
+ CC_id,
+ frameP,
+ ra->Msg2_frame,
+ ra->Msg2_slot,
+ ra->RA_rnti);
+
+ return;
+ }
+ LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
+}
+
+void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
+
+ //uint8_t i = 0;
+ int CC_id = 0;
+ gNB_MAC_INST *mac = RC.nrmac[module_idP];
+ NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+ NR_RA_t *ra = &cc->ra[0];
start_meas(&mac->schedule_ra);
+ //for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ LOG_D(MAC,"RA[state:%d]\n",ra->state);
+ switch (ra->state){
+ case Msg2:
+ nr_generate_Msg2(module_idP, CC_id, frameP, slotP);
+ break;
+ case Msg4:
+ //generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ case WAIT_Msg4_ACK:
+ //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ default:
+ break;
+ }
+ //}
+ stop_meas(&mac->schedule_ra);
+}
- for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
+ NR_BWP_Uplink_t *ubwp,
+ sub_frame_t current_slot,
+ frame_t current_frame,
+ NR_RA_t *ra) {
- for (i = 0; i < NB_RA_PROC_MAX; i++) {
+ // msg3 is schedulend in mixed slot in the following TDD period
+ // for now we consider a TBS of 18 bytes
- ra = (RA_t *) & cc[CC_id].ra[i];
- //LOG_D(MAC,"RA[state:%d]\n",ra->state);
+ int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+ int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
+ ra->Msg3_tda_id = 16; // initialization to a value above limit
- if (ra->state == MSG2)
- generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
- else if (ra->state == MSG4)
- generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
- else if (ra->state == WAITMSG4ACK)
- check_Msg4_retransmission(module_idP, CC_id, frameP, subframeP, ra);
+ for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) {
+ startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
+ SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
+ // we want to transmit in the uplink symbols of mixed slot
+ if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
+ ra->Msg3_tda_id = i;
+ break;
+ }
+ }
+ AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
- } // for i=0 .. N_RA_PROC-1
- } // CC_id
+ uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
- stop_meas(&mac->schedule_ra);
+ temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
+ ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
+ if (nr_slots_per_frame[mu]>temp_slot)
+ ra->Msg3_frame = current_frame;
+ else
+ ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
+
+ ra->msg3_nb_rb = 18;
+ ra->msg3_first_rb = 0;
+}
+
+
+void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
+ gNB_MAC_INST *mac = RC.nrmac[module_idP];
+ nfapi_nr_ul_tti_request_t *ul_req = &mac->UL_tti_req[0];
+ NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+ NR_RA_t *ra = &cc->ra[0];
+
+ if (ra->state == WAIT_Msg3) {
+ if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot) ){
+ ul_req->SFN = ra->Msg3_frame;
+ ul_req->Slot = ra->Msg3_slot;
+ ul_req->pdus_list[ul_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
+ ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
+ ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu;
+ ul_req->n_pdus+=1;
+ }
+ }
+}
+
+void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
+
+ gNB_MAC_INST *mac = RC.nrmac[module_idP];
+ NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ NR_RA_t *ra = &cc->ra[0];
+ NR_UE_list_t *UE_list = &mac->UE_list;
+ int UE_id = 0;
+
+ AssertFatal(ra->state != RA_IDLE, "RA is not active for RA %X\n", ra->rnti);
+
+ LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
+
+ nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu;
+ memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
+
+
+ AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n", UE_id);
+
+ NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
+ AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
+ "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
+ NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+ LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
+ frameP,
+ slotP,
+ ra->Msg3_frame,
+ ra->Msg3_slot,
+ ra->msg3_nb_rb,
+ ra->msg3_first_rb,
+ ra->msg3_round,
+ ra->rnti);
+
+ int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
+ int start_symbol_index,nr_of_symbols;
+ SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols);
+
+ pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
+ pusch_pdu->rnti = ra->rnti;
+ pusch_pdu->handle = 0;
+ int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+ int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+ int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275);
+ int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275);
+ if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
+ pusch_pdu->bwp_start = abwp_start;
+ else
+ pusch_pdu->bwp_start = ibwp_start;
+ pusch_pdu->bwp_size = ibwp_size;
+ pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+ pusch_pdu->cyclic_prefix = 0;
+ pusch_pdu->mcs_index = 0;
+ pusch_pdu->mcs_table = 0;
+ pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
+ pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
+ if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
+ pusch_pdu->transform_precoding = 1;
+ else
+ pusch_pdu->transform_precoding = 0;
+ pusch_pdu->data_scrambling_id = *scc->physCellId;
+ pusch_pdu->nrOfLayers = 1;
+ pusch_pdu->ul_dmrs_symb_pos = 1<dmrs_config_type = 0;
+ pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
+ pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
+ pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
+ pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
+ pusch_pdu->resource_alloc = 1; //type 1
+ pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211
+ if (ra->msg3_nb_rb > pusch_pdu->bwp_size)
+ AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
+ else
+ pusch_pdu->rb_size = ra->msg3_nb_rb;
+ pusch_pdu->vrb_to_prb_mapping = 0;
+ if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping == NULL)
+ pusch_pdu->frequency_hopping = 0;
+ else
+ pusch_pdu->frequency_hopping = 1;
+ //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
+ pusch_pdu->uplink_frequency_shift_7p5khz = 0;
+ //Resource Allocation in time domain
+ pusch_pdu->start_symbol_index = start_symbol_index;
+ pusch_pdu->nr_of_symbols = nr_of_symbols;
+ //Optional Data only included if indicated in pduBitmap
+ pusch_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213
+ pusch_pdu->pusch_data.harq_process_id = 0;
+ pusch_pdu->pusch_data.new_data_indicator = 1; // new data
+ pusch_pdu->pusch_data.num_cb = 0;
+ pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
+ pusch_pdu->target_code_rate,
+ pusch_pdu->rb_size,
+ pusch_pdu->nr_of_symbols,
+ 12, // nb dmrs set for no data in dmrs symbol
+ 0, //nb_rb_oh
+ 0, // to verify tb scaling
+ pusch_pdu->nrOfLayers = 1)>>3;
+
+ // calling function to fill rar message
+ nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu);
+
+}
+
+// WIP
+// todo:
+// - fix me
+// - get msg3 alloc (see nr_process_rar)
+void nr_generate_Msg2(module_id_t module_idP,
+ int CC_id,
+ frame_t frameP,
+ sub_frame_t slotP){
+
+ int UE_id = 0, dci_formats[2], rnti_types[2], CCEIndex, mcsIndex;
+ int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment;
+ int coreset_id, aggregation , search_space_type = 0;
+ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
+ NR_COMMON_channels_t *cc = &nr_mac->common_channels[0];
+ NR_RA_t *ra = &cc->ra[0];
+ NR_UE_list_t *UE_list = &nr_mac->UE_list;
+ NR_SearchSpace_t *ss = ra->ra_ss;
+
+ uint16_t RA_rnti = ra->RA_rnti, numDlDci;
+ long locationAndBandwidth;
+ // uint8_t *vrb_map = cc[CC_id].vrb_map, CC_id;
+
+ // check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD
+ // get the BW of the PDCCH for PDCCH size and RAR PDSCH size
+
+ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ int dci10_bw;
+
+ if (ra->coreset0_configured == 1) {
+ AssertFatal(1==0,"This is a standalone condition\n");
+ }
+ else { // on configured BWP or initial LDBWP, bandwidth parameters in DCI correspond size of initialBWP
+ locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth;
+ dci10_bw = NRRIV2BW(locationAndBandwidth,275);
+ }
+
+ if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
+
+ nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
+ nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
+
+ nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
+ memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
+ dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
+ dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
+
+ nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
+ memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
+ dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
+ dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
+
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
+ nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu;
+ numDlDci = pdcch_pdu_rel15->numDlDci;
+
+ aggregation = find_aggregation_level(ss);
+ coreset_id = *ss->controlResourceSetId;
+
+ // Checking if the DCI allocation is feasible in current subframe
+ if (dl_req->nPDUs == NFAPI_NR_MAX_DL_TTI_PDUS) {
+ LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti);
+ return;
+ } else {
+ LOG_D(MAC, "[RAPROC] Subframe %d: Checking CCE feasibility format : (%x,%d) \n", slotP, RA_rnti, aggregation);
+ CCEIndex = allocate_nr_CCEs(nr_mac, ra->bwp_id, coreset_id, aggregation, search_space_type, UE_id, 0);
+ AssertFatal(CCEIndex >= 0,"CCEIndex is negative %d\n",CCEIndex);
+ }
+
+ LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
+
+ // This code from this point on will not work on initialBWP or CORESET0
+ AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n");
+
+ NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
+ AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
+ "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
+ NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
+ NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+
+ LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
+
+ mcsIndex = 0; // Qm>2 not allowed for RAR
+
+ pdsch_pdu_rel15->pduBitmap = 0;
+ pdsch_pdu_rel15->rnti = RA_rnti;
+ pdsch_pdu_rel15->pduIndex = 0;
+
+
+ pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+ pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
+ pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
+ pdsch_pdu_rel15->CyclicPrefix = 0;
+ pdsch_pdu_rel15->NrOfCodewords = 1;
+ pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0);
+ pdsch_pdu_rel15->qamModOrder[0] = 2;
+ pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
+ if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
+ pdsch_pdu_rel15->mcsTable[0] = 0;
+ else{
+ if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
+ pdsch_pdu_rel15->mcsTable[0] = 1;
+ else
+ pdsch_pdu_rel15->mcsTable[0] = 2;
+ }
+ pdsch_pdu_rel15->rvIndex[0] = 0;
+ pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
+ pdsch_pdu_rel15->nrOfLayers = 1;
+ pdsch_pdu_rel15->transmissionScheme = 0;
+ pdsch_pdu_rel15->refPoint = 0;
+ pdsch_pdu_rel15->dmrsConfigType = 0;
+ pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
+ pdsch_pdu_rel15->SCID = 0;
+ pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2;
+ pdsch_pdu_rel15->dmrsPorts = 1;
+ pdsch_pdu_rel15->resourceAlloc = 1;
+ pdsch_pdu_rel15->rbStart = 0;
+ pdsch_pdu_rel15->rbSize = 6;
+ pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved
+
+ for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) {
+ startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
+ SLIV2SL(startSymbolAndLength, &StartSymbolIndex_tmp, &NrOfSymbols_tmp);
+ if (NrOfSymbols_tmp < NrOfSymbols) {
+ NrOfSymbols = NrOfSymbols_tmp;
+ StartSymbolIndex = StartSymbolIndex_tmp;
+ time_domain_assignment = i; // this is short PDSCH added to the config to fit mixed slot
+ }
+ }
+
+ AssertFatal(StartSymbolIndex >= 0, "StartSymbolIndex is negative\n");
+
+ pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
+ pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
+ pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols);
+
+ dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
+ dci_pdu_rel15[0].frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
+ pdsch_pdu_rel15->rbStart,dci10_bw);
+ dci_pdu_rel15[0].time_domain_assignment = time_domain_assignment;
+ dci_pdu_rel15[0].vrb_to_prb_mapping = 0;
+ dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0];
+ dci_pdu_rel15[0].tb_scaling = 0;
+
+ LOG_I(MAC, "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n",
+ dci_pdu_rel15[0].frequency_domain_assignment,
+ pdsch_pdu_rel15->rbStart,
+ pdsch_pdu_rel15->rbSize,
+ dci10_bw,
+ dci_pdu_rel15[0].time_domain_assignment,
+ dci_pdu_rel15[0].vrb_to_prb_mapping,
+ dci_pdu_rel15[0].mcs,
+ dci_pdu_rel15[0].tb_scaling);
+
+ nr_configure_pdcch(pdcch_pdu_rel15, 0, ss, scc, bwp);
+
+ LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x CCEIndex %d\n", frameP, slotP, RA_rnti, CCEIndex);
+
+ dci_pdu->RNTI[numDlDci] = RA_rnti;
+ dci_pdu->ScramblingId[numDlDci] = *scc->physCellId;
+ dci_pdu->ScramblingRNTI[numDlDci] = 0;
+ dci_pdu->AggregationLevel[numDlDci] = aggregation;
+ dci_pdu->CceIndex[numDlDci] = CCEIndex;
+ dci_pdu->beta_PDCCH_1_0[numDlDci] = 0;
+ dci_pdu->powerControlOffsetSS[numDlDci] = 1;
+ dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
+ rnti_types[0] = NR_RNTI_RA;
+
+ LOG_D(MAC, "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
+ pdcch_pdu_rel15->dci_pdu.RNTI[0],
+ rnti_types[0],
+ dci_formats[0],
+ (unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
+ pdcch_pdu_rel15->StartSymbolIndex,
+ pdcch_pdu_rel15->DurationSymbols);
+
+ pdcch_pdu_rel15->numDlDci++;
+ dci_pdu->PayloadSizeBits[0] = nr_dci_size(dci_formats[0], rnti_types[0], dci10_bw);
+ fill_dci_pdu_rel15(pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw);
+
+ dl_req->nPDUs+=2;
+
+ // Program UL processing for Msg3
+ nr_get_Msg3alloc(scc, ubwp, slotP, frameP, ra);
+ LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
+ nr_add_msg3(module_idP, CC_id, frameP, slotP);
+ ra->state = WAIT_Msg3;
+ LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+
+ x_Overhead = 0;
+ nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, 1, dci_pdu_rel15[0].tb_scaling);
+
+ // DL TX request
+ tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
+ tx_req->PDU_index = nr_mac->pdu_index[CC_id]++;
+ tx_req->num_TLV = 1;
+ tx_req->TLVs[0].length = 8;
+ nr_mac->TX_req[CC_id].SFN = frameP;
+ nr_mac->TX_req[CC_id].Number_of_PDUs++;
+ nr_mac->TX_req[CC_id].Slot = slotP;
+ memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
+ }
+}
+
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
+ NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0];
+ LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
+ ra->state = IDLE;
+ ra->timing_offset = 0;
+ ra->RRC_timer = 20;
+ ra->rnti = 0;
+ ra->msg3_round = 0;
+}
+
+
+/////////////////////////////////////
+// Random Access Response PDU //
+// TS 38.213 ch 8.2 //
+// TS 38.321 ch 6.2.3 //
+/////////////////////////////////////
+//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
+//| E | T | R A P I D |//
+//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |//
+//| R | T A |//
+//| T A | UL grant |//
+//| UL grant |//
+//| UL grant |//
+//| UL grant |//
+//| T C - R N T I |//
+//| T C - R N T I |//
+/////////////////////////////////////
+// UL grant (27 bits) //
+/////////////////////////////////////
+//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise
+//|-------------------|FHF|F_alloc|//
+//| Freq allocation |//
+//| F_alloc |Time allocation|//
+//| MCS | TPC |CSI|//
+/////////////////////////////////////
+// WIP
+// todo:
+// - handle MAC RAR BI subheader
+// - sending only 1 RAR subPDU
+// - UL Grant: hardcoded CSI, TPC, time alloc
+// - padding
+void nr_fill_rar(uint8_t Mod_idP,
+ NR_RA_t * ra,
+ uint8_t * dlsch_buffer,
+ nfapi_nr_pusch_pdu_t *pusch_pdu){
+
+ LOG_D(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d ", ra->Msg2_frame, ra-> Msg2_slot);
+ NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
+ NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1);
+ unsigned char csi_req = 0, tpc_command;
+ //uint8_t N_UL_Hop;
+ uint8_t valid_bits;
+ uint32_t ul_grant;
+ uint16_t f_alloc, prb_alloc, bwp_size, truncation=0;
+
+ tpc_command = 3; // this is 0 dB
+
+ /// E/T/RAPID subheader ///
+ // E = 0, one only RAR, first and last
+ // T = 1, RAPID
+ rarh->E = 0;
+ rarh->T = 1;
+ rarh->RAPID = ra->preamble_index;
+
+ /// RAR MAC payload ///
+ rar->R = 0;
+
+ // TA command
+ rar->TA1 = (uint8_t) (ra->timing_offset >> 5); // 7 MSBs of timing advance
+ rar->TA2 = (uint8_t) (ra->timing_offset & 0x1f); // 5 LSBs of timing advance
+
+ // TC-RNTI
+ rar->TCRNTI_1 = (uint8_t) (ra->rnti >> 8); // 8 MSBs of rnti
+ rar->TCRNTI_2 = (uint8_t) (ra->rnti & 0xff); // 8 LSBs of rnti
+
+ // UL grant
+
+ ra->msg3_TPC = tpc_command;
+
+ bwp_size = pusch_pdu->bwp_size;
+ prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size);
+ if (bwp_size>180) {
+ AssertFatal(1==0,"Initial UBWP larger than 180 currently not supported");
+ }
+ else {
+ valid_bits = (uint8_t)ceil(log2(bwp_size*(bwp_size+1)>>1));
+ }
+
+ if (pusch_pdu->frequency_hopping){
+ AssertFatal(1==0,"PUSCH with frequency hopping currently not supported");
+ } else {
+ for (int i=0; imcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26);
+
+ rar->UL_GRANT_1 = (uint8_t) (ul_grant >> 24) & 0x07;
+ rar->UL_GRANT_2 = (uint8_t) (ul_grant >> 16) & 0xff;
+ rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff;
+ rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff;
+
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 2a36425fae..5fa77c6ca7 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -31,9 +31,9 @@
*/
#include "assertions.h"
-#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_gNB/nr_mac_gNB.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 5233270149..7777e307fb 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -34,9 +34,9 @@
#include "PHY/defs_nr_common.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
/*MAC*/
-#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
-#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac.h"
+#include "NR_MAC_gNB/nr_mac_gNB.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac.h"
/*NFAPI*/
@@ -44,6 +44,9 @@
/*TAG*/
#include "NR_TAG-Id.h"
+////////////////////////////////////////////////////////
+/////* DLSCH MAC PDU generation (6.1.2 TS 38.321) */////
+////////////////////////////////////////////////////////
int nr_generate_dlsch_pdu(module_id_t module_idP,
unsigned char *sdus_payload,
@@ -61,7 +64,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
unsigned char * dlsch_buffer_ptr = sdus_payload;
uint8_t last_size = 0;
int offset = 0, mac_ce_size, i, timing_advance_cmd, tag_id = 0;
-
// MAC CEs
uint8_t mac_header_control_elements[16], *ce_ptr;
ce_ptr = &mac_header_control_elements[0];
@@ -97,6 +99,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
}
LOG_D(MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id);
+
mac_ce_size = sizeof(NR_MAC_CE_TA);
// Copying bytes for MAC CEs to the mac pdu pointer
@@ -105,7 +108,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
-
// Contention resolution fixed subheader and MAC CE
if (ue_cont_res_id) {
mac_pdu_ptr->R = 0;
@@ -130,8 +132,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
-
- // 2) Generation of DLSCH MAC SDU subheaders
+ // 2) Generation of DLSCH MAC subPDUs including subheaders and MAC SDUs
for (i = 0; i < num_sdus; i++) {
LOG_D(MAC, "[gNB] Generate DLSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]);
@@ -152,14 +153,14 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
mac_pdu_ptr += last_size;
- // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in
+ // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in
memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]);
dlsch_buffer_ptr+= sdu_lengths[i];
mac_pdu_ptr += sdu_lengths[i];
}
// 4) Compute final offset for padding
- if (post_padding > 0) {
+ if (post_padding > 0) {
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = DL_SCH_LCID_PADDING;
mac_pdu_ptr++;
@@ -170,7 +171,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
// compute final offset
offset = ((unsigned char *) mac_pdu_ptr - mac_pdu);
-
+
//printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu));
return offset;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 050f07ba67..8bbb99c3ae 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -30,8 +30,8 @@
#include "nr_mac_gNB.h"
#include "SCHED_NR/sched_nr.h"
-#include "mac_proto.h"
-#include "nr_mac_common.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "executables/nr-softmodem.h"
@@ -256,7 +256,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
int configure_fapi_dl_pdu(int Mod_idP,
int *CCEIndex,
nfapi_nr_dl_tti_request_body_t *dl_req,
- NR_sched_pucch *pucch_sched,
+ NR_sched_pucch *pucch_sched,
uint8_t *mcsIndex,
uint16_t *rbSize,
uint16_t *rbStart) {
@@ -277,6 +277,13 @@ int configure_fapi_dl_pdu(int Mod_idP,
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+ AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
+ AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
+ "searchPsacesToAddModList is empty\n");
+ NR_SearchSpace_t *ss;
+ // TO BE FIXED we are just selecting the first search space here (only one is configured)
+ ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[0];
+
dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -374,28 +381,34 @@ int configure_fapi_dl_pdu(int Mod_idP,
nr_configure_pdcch(pdcch_pdu_rel15,
1, // ue-specific
+ ss,
scc,
bwp);
pdcch_pdu_rel15->numDlDci = 1;
- pdcch_pdu_rel15->AggregationLevel[0] = 4;
- pdcch_pdu_rel15->RNTI[0]=UE_list->rnti[0];
- pdcch_pdu_rel15->CceIndex[0] = CCEIndex[0];
- pdcch_pdu_rel15->beta_PDCCH_1_0[0]=0;
- pdcch_pdu_rel15->powerControlOffsetSS[0]=1;
+ pdcch_pdu_rel15->dci_pdu.AggregationLevel[0] = 4;
+ pdcch_pdu_rel15->dci_pdu.RNTI[0]=UE_list->rnti[0];
+ pdcch_pdu_rel15->dci_pdu.ScramblingRNTI[0]=UE_list->rnti[0];
+ pdcch_pdu_rel15->dci_pdu.CceIndex[0] = CCEIndex[0];
+ pdcch_pdu_rel15->dci_pdu.beta_PDCCH_1_0[0]=0;
+ pdcch_pdu_rel15->dci_pdu.powerControlOffsetSS[0]=1;
int dci_formats[2];
int rnti_types[2];
- dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
+ if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
+ dci_formats[0] = NR_DL_DCI_FORMAT_1_1;
+ else
+ dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
+
rnti_types[0] = NR_RNTI_C;
- pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
- fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types);
+ pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
+ fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,pdcch_pdu_rel15->BWPSize);
- LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d\n \
+ LOG_D(MAC, "DCI params: rnti %x, rnti_type %d, dci_format %d\n \
coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
- pdcch_pdu_rel15->RNTI[0],
+ pdcch_pdu_rel15->dci_pdu.RNTI[0],
rnti_types[0],
dci_formats[0],
(unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
@@ -403,7 +416,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
pdcch_pdu_rel15->DurationSymbols);
int x_Overhead = 0; // should be 0 for initialBWP
- nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead);
+ nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead,1,0);
// Hardcode it for now
TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0];
@@ -437,7 +450,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr
dci_pdu_rel15->tpc = 2;
LOG_D(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n",
- pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci],
+ pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci],
dci_pdu_rel15->frequency_domain_assignment,
dci_pdu_rel15->time_domain_assignment,
dci_pdu_rel15->frequency_hopping_flag,
@@ -484,7 +497,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP,
tx_req->num_TLV = 1;
tx_req->TLVs[0].length = tbs_bytes +2;
- memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes);;
+ memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes);
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].SFN = frameP;
@@ -533,8 +546,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
UE_id,
0); // m
- if (CCEIndex == -1) return;
-
AssertFatal(CCEIndex>0,"CCEIndex is negative\n");
int CCEIndices[2];
CCEIndices[0] = CCEIndex;
@@ -542,7 +553,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
TBS_bytes = configure_fapi_dl_pdu(module_idP,
CCEIndices,
dl_req,
- pucch_sched,
+ pucch_sched,
dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL,
dlsch_config!=NULL ? &dlsch_config->rbSize : NULL,
dlsch_config!=NULL ? &dlsch_config->rbStart : NULL);
@@ -612,10 +623,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
// fill dlsch_buffer with random data
for (i = 0; i < TBS_bytes; i++){
- //mac_sdus[i] = (unsigned char) rand();
- ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
+ mac_sdus[i] = (unsigned char) (lrand48()&0xff);
+ //((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
}
-
//Sending SDUs with size 1
//Initialize elements of sdu_lcids and sdu_lengths
sdu_lcids[0] = 0x05; // DRB
@@ -652,7 +662,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
offset = nr_generate_dlsch_pdu(module_idP,
(unsigned char *) mac_sdus,
- (unsigned char *) gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0], //(unsigned char *) mac_pdu,
+ (unsigned char *) gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0],
num_sdus, //num_sdus
sdu_lengths,
sdu_lcids,
@@ -715,6 +725,12 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
+ AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
+ AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
+ "searchPsacesToAddModList is empty\n");
+ NR_SearchSpace_t *ss;
+ // TO BE FIXED we are just selecting the first search space here (only one is configured)
+ ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[0];
uint16_t rnti = UE_list->rnti[UE_id];
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu;
@@ -809,13 +825,22 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
pusch_pdu->pusch_data.rv_index = 0;
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = 0;
+
+ uint8_t no_data_in_dmrs = 1; // temp implementation
+ uint8_t num_dmrs_symb = 0;
+
+ for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++)
+ num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1);
+
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
- pusch_pdu->dmrs_config_type?4:6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI
+ ( no_data_in_dmrs ? 12 : ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1) ? 6 : 4) ) * num_dmrs_symb,
0, //nb_rb_oh
+ 0,
pusch_pdu->nrOfLayers)>>3;
+
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
//pusch_pdu->pusch_data.cb_present_and_position;
//pusch_pdu->pusch_uci;
@@ -847,20 +872,21 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
nr_configure_pdcch(pdcch_pdu_rel15,
1, // ue-specific,
+ ss,
scc,
bwp);
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
AssertFatal(CCEIndex>=0,"CCEIndex is negative \n");
- pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci] = CCEIndex;
+ pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci] = CCEIndex;
- LOG_D(PHY,"CCEIndex %d\n",pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci]);
+ LOG_D(PHY,"CCEIndex %d\n",pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci]);
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types);
- pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
- fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types);
+ pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize);
+ fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,pdcch_pdu_rel15->BWPSize);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 6d3f69f217..d3412095e3 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -33,10 +33,10 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
-#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_gNB/nr_mac_gNB.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/nr/nr_common.h"
@@ -129,14 +129,33 @@ static inline uint8_t get_max_cces(uint8_t scs) {
return (nr_max_number_of_cces_per_slot[scs]);
}
+int find_aggregation_level (NR_SearchSpace_t *ss){
+
+ int level = 0;
+
+ if( ss->nrofCandidates->aggregationLevel1 != NR_SearchSpace__nrofCandidates__aggregationLevel1_n0)
+ level = 1;
+ if( ss->nrofCandidates->aggregationLevel2 != NR_SearchSpace__nrofCandidates__aggregationLevel2_n0)
+ level = 2;
+ if( ss->nrofCandidates->aggregationLevel4 != NR_SearchSpace__nrofCandidates__aggregationLevel4_n0)
+ level = 4;
+ if( ss->nrofCandidates->aggregationLevel8 != NR_SearchSpace__nrofCandidates__aggregationLevel8_n0)
+ level = 8;
+ if( ss->nrofCandidates->aggregationLevel16 != NR_SearchSpace__nrofCandidates__aggregationLevel16_n0)
+ level = 16;
+
+ AssertFatal(level!=0,"Unable to find aggregation level");
+ return level;
+
+}
+
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int bwp_id,
int coreset_id,
int aggregation,
int search_space, // 0 common, 1 ue-specific
int UE_id,
- int m
- ) {
+ int m) {
// uncomment these when we allocate for common search space
// NR_COMMON_channels_t *cc = nr_mac->common_channels;
// NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -148,14 +167,15 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
NR_ControlResourceSet_t *coreset;
+ AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id);
+ secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
+ bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
+
if (search_space == 1) {
- AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id);
- secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
- bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[coreset_id];
}
else {
- AssertFatal(1==0,"Add code for common search space\n");
+ coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
}
int *cce_list = nr_mac->cce_list[bwp_id][coreset_id];
@@ -411,63 +431,75 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
int ss_type,
+ NR_SearchSpace_t *ss,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp){
+ NR_ControlResourceSet_t *coreset = NULL;
+
if (bwp) { // This is not the InitialBWP
- /// coreset
-
- //ControlResourceSetId
- // pdcch_pdu->config_type = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
- AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL,
- "controlResourceSetToAddModList is null\n");
- AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count>0,
- "controlResourceSetToAddModList is empty\n");
- NR_ControlResourceSet_t *coreset0 = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[0];
-
+ NR_ControlResourceSet_t *temp_coreset;
+ NR_ControlResourceSetId_t coresetid = *ss->controlResourceSetId;
+ if (ss_type == 0) { // common search space
+ if (coresetid == 0){
+ AssertFatal(1==0,"coreset0 currently not supported\n");
+ }
+ else {
+ coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
+ AssertFatal(coresetid==coreset->controlResourceSetId,"ID of common ss coreset does not correspond to id set in the search space\n");
+ }
+ }
+ else {
+ int n_list = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
+ for (int i=0; ibwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
+ if (coresetid==temp_coreset->controlResourceSetId) {
+ coreset = temp_coreset;
+ break;
+ }
+ }
+ if(coreset==NULL)
+ AssertFatal(1==0,"Couldn't find coreset with id %ld\n",coresetid);
+ }
pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
pdcch_pdu->CyclicPrefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix;
- pdcch_pdu->DurationSymbols = coreset0->duration;
+
+ // first symbol
+ //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
+ int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+
+ AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
+ AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
- //frequencyDomainResources
- /* uint8_t count=0, start=0, start_set=0;
- // find coreset descriptor
+ // for SPS=14 8 MSBs in positions 13 downto 6
+ uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
+ (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
+
+ for (int i=0; i>(sps-1-i))&1) {
+ pdcch_pdu->StartSymbolIndex=i;
+ break;
+ }
+ }
+
+ pdcch_pdu->DurationSymbols = coreset->duration;
- uint64_t bitmap = (((uint64_t)coreset0->frequencyDomainResources.buf[0])<<37)|
- (((uint64_t)coreset0->frequencyDomainResources.buf[1])<<29)|
- (((uint64_t)coreset0->frequencyDomainResources.buf[2])<<21)|
- (((uint64_t)coreset0->frequencyDomainResources.buf[3])<<13)|
- (((uint64_t)coreset0->frequencyDomainResources.buf[4])<<5)|
- (((uint64_t)coreset0->frequencyDomainResources.buf[5])>>3);
-
- for (int i=0; i<45; i++)
- if ((bitmap>>(44-i))&1) {
- count++;
- if (!start_set) {
- start = i;
- start_set = 1;
- }
- }
- pdcch_pdu->rb_offset = 6*start;
- pdcch_pdu->n_rb = 6*count;
- */
for (int i=0;i<6;i++)
- pdcch_pdu->FreqDomainResource[i] = coreset0->frequencyDomainResources.buf[i];
- //duration
-
+ pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i];
//cce-REG-MappingType
- pdcch_pdu->CceRegMappingType = coreset0->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
+ pdcch_pdu->CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved?
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED;
+
if (pdcch_pdu->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
- pdcch_pdu->RegBundleSize = (coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
- pdcch_pdu->InterleaverSize = (coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize);
+ pdcch_pdu->RegBundleSize = (coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize);
+ pdcch_pdu->InterleaverSize = (coreset->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->interleaverSize);
AssertFatal(scc->physCellId != NULL,"scc->physCellId is null\n");
- pdcch_pdu->ShiftIndex = coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
+ pdcch_pdu->ShiftIndex = coreset->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId;
}
else {
pdcch_pdu->RegBundleSize = 0;
@@ -478,65 +510,16 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
pdcch_pdu->CoreSetType = 1;
//precoderGranularity
- pdcch_pdu->precoderGranularity = coreset0->precoderGranularity;
+ pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
- //TCI states
- //
- /*
- //TCI present
- if (coreset0->tci_PresentInDCI != NULL) {
- AssertFatal(coreset0->tci_StatesPDCCH_ToAddList != NULL,"tci_StatesPDCCH_ToAddList is null\n");
- AssertFatal(coreset0->tci_StatesPDCCH_ToAddList->list.count>0,"TCI state list is empty\n");
- for (int i=0;itci_StatesPDCCH_ToAddList->list.count;i++) {
-
- }
- */
-
- for (int i=0;inumDlDci;i++) {
- //pdcch-DMRS-ScramblingID
- AssertFatal(coreset0->pdcch_DMRS_ScramblingID != NULL,"coreset0->pdcch_DMRS_ScramblingID is null\n");
- pdcch_pdu->ScramblingId[i] = *coreset0->pdcch_DMRS_ScramblingID;
- }
-
- /// SearchSpace
-
- // first symbol
- //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
- int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
-
- AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
- AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
- "searchPsacesToAddModList is empty\n");
- NR_SearchSpace_t *ss=NULL;
- int found=0;
- int target_ss = NR_SearchSpace__searchSpaceType_PR_common;
- if (ss_type == 1) {
- target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
- }
-
- for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
- ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
- AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
- AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
- if (*ss->controlResourceSetId == coreset0->controlResourceSetId &&
- ss->searchSpaceType->present == target_ss) {
- found=1;
- break;
+ if (ss_type) {
+ for (int i=0;inumDlDci;i++) {
+ //pdcch-DMRS-ScramblingID
+ AssertFatal(coreset->pdcch_DMRS_ScramblingID != NULL,"coreset0->pdcch_DMRS_ScramblingID is null\n");
+ pdcch_pdu->dci_pdu.ScramblingId[i] = *coreset->pdcch_DMRS_ScramblingID;
}
}
- AssertFatal(found==1,"Couldn't find a searchspace corresponding to coreset0\n");
- AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
- AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
-
- // for SPS=14 8 MSBs in positions 13 downto 6,
- uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) |
- (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
-
- for (int i=0; i>(sps-1-i))&1) {
- pdcch_pdu->StartSymbolIndex=i;
- break;
- }
+
}
else { // this is for InitialBWP
@@ -734,18 +717,21 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
- int *rnti_types) {
+ int *rnti_types,
+ int N_RB) {
- uint16_t N_RB = pdcch_pdu_rel15->BWPSize;
+
uint8_t fsize=0, pos=0;
for (int d=0;dnumDlDci;d++) {
- uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->Payload[d];
- AssertFatal(pdcch_pdu_rel15->PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported");
+ uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->dci_pdu.Payload[d];
+ AssertFatal(pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported");
+
+ int dci_size = pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d];
+
+ *dci_pdu=0;
- int dci_size = pdcch_pdu_rel15->PayloadSizeBits[d];
-
/// Payload generation
switch(dci_formats[d]) {
case NR_DL_DCI_FORMAT_1_0:
@@ -754,25 +740,35 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
// Freq domain assignment
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos=fsize;
- *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_size-pos,*dci_pdu);
+ *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_size-pos,*dci_pdu);
+#endif
// Time domain assignment
pos+=4;
*dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment&0xf) << (dci_size-pos));
- LOG_D(MAC,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,dci_size-pos,*dci_pdu);
+#ifdef DEBUG_FILL_DCI
+ LOG_I(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,dci_size-pos,*dci_pdu);
+#endif
// VRB to PRB mapping
pos++;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_size-pos);
- LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,dci_size-pos,*dci_pdu);
+#ifdef DEBUG_FILL_DCI
+ LOG_I(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,dci_size-pos,*dci_pdu);
+#endif
// MCS
pos+=5;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos);
- LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu);
+#ifdef DEBUG_FILL_DCI
+ LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu);
+#endif
// TB scaling
pos+=2;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling&0x3)<<(dci_size-pos);
- LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu);
+#ifdef DEBUG_FILL_DCI
+ LOG_I(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu);
+#endif
break;
case NR_RNTI_C:
@@ -1089,7 +1085,6 @@ int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot) {
}
-
int extract_startSymbol(int startSymbolAndLength) {
int tmp = startSymbolAndLength/14;
int tmp2 = startSymbolAndLength%14;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 2b7c2274eb..0e42d79fdc 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -28,10 +28,12 @@
* @ingroup _mac
*/
+
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "executables/softmodem-common.h"
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
+
void nr_process_mac_pdu(
module_id_t module_idP,
uint8_t CC_id,
@@ -87,7 +89,13 @@ void nr_process_mac_pdu(
/*#ifdef DEBUG_HEADER_PARSING
LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len);
#endif*/
-
+ case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
+ // 38.321 Ch6.1.3.20
+ mac_ce_len = 2;
+ break;
+ case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
+ // 38.321 Ch6.1.3.7
+ break;
case UL_SCH_LCID_S_BSR:
//38.321 section 6.1.3.1
//fixed length
@@ -170,6 +178,24 @@ void nr_process_mac_pdu(
// end of MAC PDU, can ignore the rest.
break;
+ // MAC SDUs
+ case UL_SCH_LCID_SRB1:
+ // todo
+ break;
+ case UL_SCH_LCID_SRB2:
+ // todo
+ break;
+ case UL_SCH_LCID_SRB3:
+ // todo
+ break;
+ case UL_SCH_LCID_CCCH_MSG3:
+ // todo
+ break;
+ case UL_SCH_LCID_CCCH:
+ // todo
+ mac_subheader_len = 2;
+ break;
+
case UL_SCH_LCID_DTCH:
// check if LCID is valid at current time.
if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){
@@ -183,7 +209,7 @@ void nr_process_mac_pdu(
mac_subheader_len = 2;
}
- LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
+ LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
@@ -223,13 +249,12 @@ void nr_process_mac_pdu(
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
if (pdu_len < 0) {
- LOG_E(MAC, "%s() residual mac pdu length < 0!\n", __func__);
+ LOG_E(MAC, "%s() residual mac pdu length < 0!, pdu_len: %d\n", __func__, pdu_len);
return;
}
}
}
-
/*
* When data are received on PHY and transmitted to MAC
*/
@@ -282,3 +307,4 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
}
}
}
+
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index c0f4053c03..c6e24399b0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -31,8 +31,9 @@
#ifndef __LAYER2_NR_MAC_PROTO_H__
#define __LAYER2_NR_MAC_PROTO_H__
-#include "nr_mac_gNB.h"
#include "PHY/defs_gNB.h"
+
+#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_TAG-Id.h"
#define MAX_ACK_BITS 2 //only format 0 is available for now
@@ -78,6 +79,48 @@ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slo
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
+/////// Random Access MAC-PHY interface functions and primitives ///////
+
+void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
+
+/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
+@param module_idP Instance ID of gNB
+@param preamble_index index of the received RA request
+@param slotP Slot number on which to act
+@param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to
+@param rnti RA rnti corresponding to this PRACH preamble
+@param rach_resource type (0=non BL/CE,1 CE level 0,2 CE level 1, 3 CE level 2,4 CE level 3)
+*/
+void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP,
+ uint16_t preamble_index, uint8_t freq_index, uint8_t symbol, int16_t timing_offset);
+
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
+
+int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
+
+void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
+ NR_BWP_Uplink_t *ubwp,
+ sub_frame_t current_subframe,
+ frame_t current_frame,
+ NR_RA_t *ra);
+
+/* \brief Function in gNB to fill RAR pdu when requested by PHY.
+@param ra Instance of RA resources of gNB
+@param dlsch_buffer Pointer to RAR input buffer
+@param N_RB_UL Number of UL resource blocks
+*/
+void nr_fill_rar(uint8_t Mod_idP,
+ NR_RA_t * ra,
+ uint8_t * dlsch_buffer,
+ nfapi_nr_pusch_pdu_t *pusch_pdu);
+
+
+void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
+
+uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
+
+/////// Phy test scheduler ///////
+
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP);
@@ -149,21 +192,24 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
uint8_t SR_flag);
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
int ss_type,
+ NR_SearchSpace_t *ss,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp);
void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
- int *rnti_types);
+ int *rnti_types,
+ int N_RB);
+
int get_spf(nfapi_nr_config_request_scf_t *cfg);
int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot);
-void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
-
void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
- int x_overhead);
+ int x_overhead,
+ uint8_t nodata_dmrs,
+ uint8_t tb_scaling);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
@@ -182,17 +228,6 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
-int get_num_dmrs(uint16_t dmrs_mask );
-uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
-int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength);
-
-uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
-uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
-
-uint16_t nr_dci_size(nr_dci_format_t format,
- nr_rnti_type_t rnti_type,
- uint16_t N_RB);
-
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int bwp_id,
int coreset_id,
@@ -202,9 +237,6 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int m
);
-int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
-int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
-
int get_dlscs(nfapi_nr_config_request_t *cfg);
int get_ulscs(nfapi_nr_config_request_t *cfg);
@@ -224,6 +256,15 @@ void config_nr_mib(int Mod_idP,
int intraFreqReselection);
+void nr_generate_Msg2(module_id_t module_idP,
+ int CC_id,
+ frame_t frameP,
+ sub_frame_t slotP);
+
+void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP);
+
+int find_aggregation_level (NR_SearchSpace_t *ss);
+
void nr_process_mac_pdu(
module_id_t module_idP,
uint8_t CC_id,
@@ -231,6 +272,7 @@ void nr_process_mac_pdu(
uint8_t *pduP,
uint16_t mac_pdu_len);
+
/* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of gNB
@param CC_id Component carrier index
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 9e8415776b..d38a251a2b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -30,8 +30,8 @@
*/
-#include "mac_proto.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "assertions.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c
index e4e3ac05df..df23b64e07 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c
@@ -39,6 +39,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
+ uint8_t tb_scaling,
uint8_t Nl)
{
@@ -54,7 +55,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
scale = (R>1024)?11:10;
// Intermediate number of information bits
- Ninfo = (nb_re * R * Qm * Nl)>>scale;
+ Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling;
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index bf9358dd43..90d2310f77 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -42,30 +42,106 @@
#include
#include
+/* Commmon */
+#include "targets/ARCH/COMMON/common_lib.h"
+#include "COMMON/platform_constants.h"
+#include "common/ran_context.h"
+
+/* RRC */
#include "NR_BCCH-BCH-Message.h"
#include "NR_CellGroupConfig.h"
#include "NR_ServingCellConfigCommon.h"
#include "NR_MeasConfig.h"
+/* PHY */
+#include "PHY/defs_gNB.h"
+#include "PHY/TOOLS/time_meas.h"
+
+/* Interface */
#include "nfapi_nr_interface_scf.h"
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
-#include "COMMON/platform_constants.h"
-#include "common/ran_context.h"
+/* MAC */
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
-#include "PHY/defs_gNB.h"
-#include "PHY/TOOLS/time_meas.h"
-#include "targets/ARCH/COMMON/common_lib.h"
-
-#include "nr_mac_common.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
+#include "NR_TAG.h"
+/* Defs */
#define MAX_NUM_BWP 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CCE 90
+/*!\brief Maximum number of random access process */
+#define NR_NB_RA_PROC_MAX 4
-#include "NR_TAG.h"
+typedef enum {
+ RA_IDLE = 0,
+ Msg2 = 1,
+ WAIT_Msg3 = 2,
+ Msg4 = 3,
+ WAIT_Msg4_ACK = 4
+} RA_gNB_state_t;
+
+/*! \brief gNB template for the Random access information */
+typedef struct {
+ /// Flag to indicate this process is active
+ RA_gNB_state_t state;
+ /// BWP id of RA process
+ int bwp_id;
+ /// CORESET0 configured flag
+ int coreset0_configured;
+ /// Slot where preamble was received
+ uint8_t preamble_slot;
+ /// Subframe where Msg2 is to be sent
+ uint8_t Msg2_slot;
+ /// Frame where Msg2 is to be sent
+ frame_t Msg2_frame;
+ /// Subframe where Msg3 is to be sent
+ sub_frame_t Msg3_slot;
+ /// Frame where Msg3 is to be sent
+ frame_t Msg3_frame;
+ /// Msg3 time domain allocation index
+ uint8_t Msg3_tda_id;
+ /// Subframe where Msg4 is to be sent
+ sub_frame_t Msg4_slot;
+ /// Frame where Msg4 is to be sent
+ frame_t Msg4_frame;
+ /// harq_pid used for Msg4 transmission
+ uint8_t harq_pid;
+ /// UE RNTI allocated during RAR
+ rnti_t rnti;
+ /// RA RNTI allocated from received PRACH
+ uint16_t RA_rnti;
+ /// Received preamble_index
+ uint8_t preamble_index;
+ /// Received UE Contention Resolution Identifier
+ uint8_t cont_res_id[6];
+ /// Timing offset indicated by PHY
+ int16_t timing_offset;
+ /// Timeout for RRC connection
+ int16_t RRC_timer;
+ /// Msg3 first RB
+ uint8_t msg3_first_rb;
+ /// Msg3 number of RB
+ uint8_t msg3_nb_rb;
+ /// Msg3 TPC command
+ uint8_t msg3_TPC;
+ /// Msg3 ULdelay command
+ uint8_t msg3_ULdelay;
+ /// Msg3 cqireq command
+ uint8_t msg3_cqireq;
+ /// Round of Msg3 HARQ
+ uint8_t msg3_round;
+ /// Msg3 pusch pdu
+ nfapi_nr_pusch_pdu_t pusch_pdu;
+ /// TBS used for Msg4
+ int msg4_TBsize;
+ /// MCS used for Msg4
+ int msg4_mcs;
+ /// RA search space
+ NR_SearchSpace_t *ra_ss;
+} NR_RA_t;
/*! \brief gNB common channels */
typedef struct {
@@ -73,6 +149,7 @@ typedef struct {
int p_gNB;
int Ncp;
int nr_band;
+ lte_frame_type_t frame_type;
uint64_t dl_CarrierFreq;
NR_BCCH_BCH_Message_t *mib;
NR_ServingCellConfigCommon_t *ServingCellConfigCommon;
@@ -93,7 +170,7 @@ typedef struct {
/// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu;
/// Template for RA computations
- RA_t ra[NB_RA_PROC_MAX];
+ NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
uint8_t vrb_map[100];
/// VRB map for common channels and retransmissions by PHICH
@@ -120,9 +197,8 @@ typedef struct {
int16_t ta_update;
} NR_UE_sched_ctrl_t;
-/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
+/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
typedef struct {
-
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
/// scheduling control info
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
@@ -208,11 +284,11 @@ typedef struct {
uint16_t frequency_domain_assignment; //up to 16 bits
uint8_t time_domain_assignment; // 4 bits
uint8_t frequency_hopping_flag; //1 bit
-
+
uint8_t ra_preamble_index; //6 bits
uint8_t ss_pbch_index; //6 bits
uint8_t prach_mask_index; //4 bits
-
+
uint8_t vrb_to_prb_mapping; //0 or 1 bit
uint8_t mcs; //5 bits
uint8_t ndi; //1 bit
@@ -224,11 +300,11 @@ typedef struct {
uint8_t tpc; //2 bits
uint8_t pucch_resource_indicator; //3 bits
uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
-
+
uint8_t short_messages_indicator; //2 bits
uint8_t short_messages; //8 bits
uint8_t tb_scaling; //2 bits
-
+
uint8_t carrier_indicator; //0 or 3 bits
uint8_t bwp_indicator; //0, 1 or 2 bits
uint8_t prb_bundling_size_indicator; //0 or 1 bits
@@ -239,30 +315,28 @@ typedef struct {
uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
uint8_t dmrs_sequence_initialization; //0 or 1 bit
-
+
uint8_t srs_resource_indicator;
uint8_t precoding_information;
uint8_t csi_request;
uint8_t ptrs_dmrs_association;
uint8_t beta_offset_indicator; //0 or 2 bits
-
+
uint8_t slot_format_indicator_count;
uint8_t *slot_format_indicators;
-
+
uint8_t pre_emption_indication_count;
uint16_t *pre_emption_indications; //14 bit
-
+
uint8_t block_number_count;
uint8_t *block_numbers;
-
+
uint8_t ul_sul_indicator; //0 or 1 bit
uint8_t antenna_ports;
-
+
uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
uint16_t padding;
} dci_pdu_rel15_t;
-
-
#endif /*__LAYER2_NR_MAC_GNB_H__ */
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index b0e6143de1..3667af2698 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -503,8 +503,6 @@ pdcp_data_ind(
//-----------------------------------------------------------------------------
{
pdcp_t *pdcp_p = NULL;
- list_t *sdu_list_p = NULL;
- mem_block_t *new_sdu_p = NULL;
uint8_t pdcp_header_len = 0;
uint8_t pdcp_tailer_len = 0;
pdcp_sn_t sequence_number = 0;
@@ -576,7 +574,6 @@ pdcp_data_ind(
}
}
- sdu_list_p = &pdcp_sdu_list;
if (sdu_buffer_sizeP == 0) {
LOG_W(PDCP, "SDU buffer size is zero! Ignoring this chunk!\n");
@@ -974,9 +971,8 @@ pdcp_data_ind(
#endif
if (FALSE == packet_forwarded) {
- new_sdu_p = get_free_mem_block(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), __func__);
+ notifiedFIFO_elt_t * new_sdu_p = newNotifiedFIFO_elt(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), 0, NULL, NULL);
- if (new_sdu_p) {
if ((MBMS_flagP == 0) && (pdcp_p->rlc_mode == RLC_MODE_AM)) {
pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
}
@@ -984,14 +980,15 @@ pdcp_data_ind(
/*
* Prepend PDCP indication header which is going to be removed at pdcp_fifo_flush_sdus()
*/
- memset(new_sdu_p->data, 0, sizeof (pdcp_data_ind_header_t));
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size = sdu_buffer_sizeP - payload_offset;
+ pdcp_data_ind_header_t * pdcpHead=(pdcp_data_ind_header_t *)NotifiedFifoData(new_sdu_p);
+ memset(pdcpHead, 0, sizeof (pdcp_data_ind_header_t));
+ pdcpHead->data_size = sdu_buffer_sizeP - payload_offset;
AssertFatal((sdu_buffer_sizeP - payload_offset >= 0), "invalid PDCP SDU size!");
// Here there is no virtualization possible
// set ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst for IP layer here
if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id;
+ pdcpHead->rb_id = rb_id;
if (EPC_MODE_ENABLED) {
/* for the UE compiled in S1 mode, we need 1 here
@@ -1002,45 +999,40 @@ pdcp_data_ind(
#ifdef UESIM_EXPANSION
if (UE_NAS_USE_TUN) {
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
+ pdcpHead->inst = ctxt_pP->module_id;
} else {
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = 0;
+ pdcpHead->inst = 0;
}
#else
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
+ pdcpHead->inst = ctxt_pP->module_id;
#endif
} else { // nfapi_mode
if (UE_NAS_USE_TUN) {
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
+ pdcpHead->inst = ctxt_pP->module_id;
} else {
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = 1;
+ pdcpHead->inst = 1;
}
} // nfapi_mode
}
} else {
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB);
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id;
+ pdcpHead->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB);
+ pdcpHead->inst = ctxt_pP->module_id;
}
if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
static uint32_t pdcp_inst = 0;
- ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = pdcp_inst++;
- LOG_D(PDCP, "inst=%d size=%d\n", ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst, ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size);
+ pdcpHead->inst = pdcp_inst++;
+ LOG_D(PDCP, "inst=%d size=%d\n", pdcpHead->inst, pdcpHead->data_size);
}
- memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)],
+ memcpy(pdcpHead+1,
&sdu_buffer_pP->data[payload_offset],
sdu_buffer_sizeP - payload_offset);
-
- #if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
- LOG_I(PDCP, "Printing first bytes of PDCP SDU before adding it to the list: \n");
- for (int i=0; i<30; i++){
- LOG_I(PDCP, "%x", sdu_buffer_pP->data[i]);
- }
- #endif
- list_add_tail_eurecom (new_sdu_p, sdu_list_p);
- }
+ if( LOG_DEBUGFLAG(DEBUG_PDCP) )
+ log_dump(PDCP, pdcpHead+1, min(sdu_buffer_sizeP - payload_offset,30) , LOG_DUMP_CHAR,
+ "Printing first bytes of PDCP SDU before adding it to the list: \n");
+ pushNotifiedFIFO(&pdcp_sdu_list, new_sdu_p);
/* Print octets of incoming data in hexadecimal form */
LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n",
@@ -2390,7 +2382,7 @@ void nr_ip_over_LTE_DRB_preconfiguration(void){
// 1 + drb_identiy_index;
DRB_config->drb_Identity = 1;
DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
- *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
+ *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 3; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
DRB_config->rlc_Config = DRB_rlc_config;
@@ -2467,7 +2459,7 @@ void pdcp_layer_init(void)
/*
* Initialize SDU list
*/
- list_init(&pdcp_sdu_list, NULL);
+ initNotifiedFIFO(&pdcp_sdu_list);
pdcp_coll_p = hashtable_create ((LTE_maxDRB + 2) * NUMBER_OF_UE_MAX, NULL, pdcp_free);
AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed");
@@ -2540,7 +2532,8 @@ void pdcp_layer_init(void)
void pdcp_layer_cleanup (void)
//-----------------------------------------------------------------------------
{
- list_free (&pdcp_sdu_list);
+ //list_free (&pdcp_sdu_list);
+ while(pollNotifiedFIFO(&pdcp_sdu_list)) {};
hashtable_destroy(&pdcp_coll_p);
#ifdef MBMS_MULTICAST_OUT
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index e9ac85866c..8e265e8cf1 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -522,7 +522,7 @@ pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceC
sdu_size_t pdcp_output_sdu_bytes_to_write;
sdu_size_t pdcp_output_header_bytes_to_write;
-list_t pdcp_sdu_list;
+notifiedFIFO_t pdcp_sdu_list;
int pdcp_sent_a_sdu;
pdcp_data_req_header_t pdcp_input_header;
unsigned char pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index d203408e55..14d95b15b3 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -111,69 +111,59 @@ void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) {
}
//-----------------------------------------------------------------------------
int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
- mem_block_t *sdu_p;
+ notifiedFIFO_elt_t *sdu_p;
int pdcp_nb_sdu_sent = 0;
int ret=0;
+ while ((sdu_p = pollNotifiedFIFO(&pdcp_sdu_list)) != NULL ) {
+ pdcp_data_ind_header_t * pdcpHead=(pdcp_data_ind_header_t *)NotifiedFifoData(sdu_p);
+ AssertFatal(pdcpHead->inst==ctxt_pP->module_id, "To implement correctly multi module id\n");
- while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
- ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
- int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
+ int rb_id = pdcpHead->rb_id;
int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
- ((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
+ pdcpHead->data_size;
+ void * pdcpData=(void*)(pdcpHead+1);
if (rb_id == 10) { //hardcoded for PC5-Signaling
if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
- debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)&(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
+ debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)pdcpData,
"pdcp_fifo_flush_sdus sends a aPC5S message");
}
- ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
+ ret = sendto(pdcp_pc5_sockfd, pdcpData,
sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) );
} else if (UE_NAS_USE_TUN) {
//ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
if(rb_id == mbms_rab_id){
- ret = write(nas_sock_mbms_fd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
- LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
+ ret = write(nas_sock_mbms_fd, pdcpData,sizeToWrite );
+ LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",
+ ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
else
{
- #if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
- LOG_I(PHY, "PDCP output to be sent to TUN interface: \n");
- for (int i = sizeof(pdcp_data_ind_header_t); i < sizeToWrite; i++) {
- printf("%02x ",(unsigned char)sdu_p->data[i]);
- }
- printf("\n");
- #endif
- ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
- //LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
+ if( LOG_DEBUGFLAG(DEBUG_PDCP) )
+ log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
+ ret = write(nas_sock_fd[ctxt_pP->module_id], pdcpData,sizeToWrite );
+ LOG_T(PDCP,"[UE PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",
+ ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
} else if (ENB_NAS_USE_TUN) {
- #if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
- LOG_I(PHY, "PDCP output to be sent to TUN interface: \n");
- for (int i = sizeof(pdcp_data_ind_header_t); i < sizeToWrite; i++) {
- printf("%02x ",(unsigned char)sdu_p->data[i]);
- }
- printf("\n");
- #endif
- ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), sizeToWrite);
-
+ if( LOG_DEBUGFLAG(DEBUG_PDCP) )
+ log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
+ ret = write(nas_sock_fd[0], pdcpData, sizeToWrite);
+ LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],sizeToWrite);
} else if (PDCP_USE_NETLINK) {
- memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite);
+ memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) pdcpHead, sizeToWrite);
nas_nlh_tx->nlmsg_len = sizeToWrite;
ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
} // PDCP_USE_NETLINK
AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]);
- #if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
- LOG_I(PDCP, "Printing first bytes of PDCP SDU before removing it from the list: \n");
- for (int i=0; i<30; i++){
- LOG_I(PDCP, "%x", sdu_p->data[i]);
- }
- #endif
- list_remove_head (&pdcp_sdu_list);
- free_mem_block (sdu_p, __func__);
+ if( LOG_DEBUGFLAG(DEBUG_PDCP) )
+ log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR,
+ "Printing first bytes of PDCP SDU before removing it from the list: \n");
+ delNotifiedFIFO_elt (sdu_p);
pdcp_nb_sdu_sent ++;
}
@@ -181,12 +171,13 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
}
int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) {
- mem_block_t *sdu_p;
+ notifiedFIFO_elt_t *sdu_p;
int pdcp_nb_sdu_sent = 0;
//int ret=0;
- while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
- ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
+ while ((sdu_p = pollNotifiedFIFO(&pdcp_sdu_list)) != NULL ) {
+ pdcp_data_ind_header_t * pdcpHead=(pdcp_data_ind_header_t *)NotifiedFifoData(sdu_p);
+ AssertFatal(pdcpHead->inst==ctxt_pP->module_id, "To implement correctly multi module id\n");
//int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
//int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
//((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
@@ -212,8 +203,8 @@ int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) {
//} // PDCP_USE_NETLINK
//AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
- list_remove_head (&pdcp_sdu_list);
- free_mem_block (sdu_p, __func__);
+ //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
+ delNotifiedFIFO_elt (sdu_p);
pdcp_nb_sdu_sent ++;
}
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index ff0d446e3f..bbc4acbd56 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -72,8 +72,8 @@ void mac_rlc_data_ind (
LOG_I(RLC, "RLC instance for the given UE was not found \n");
switch (channel_idP) {
- case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
- case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
+ case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
+ case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -113,8 +113,8 @@ tbs_size_t mac_rlc_data_req(
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
switch (channel_idP) {
- case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
- case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
+ case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
+ case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -123,7 +123,7 @@ tbs_size_t mac_rlc_data_req(
maxsize = tb_sizeP;
ret = rb->generate_pdu(rb, buffer_pP, maxsize);
} else {
- LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB\n", __FILE__, __LINE__, __FUNCTION__);
+ LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB, channel_idP: %d\n", __FILE__, __LINE__, __FUNCTION__, channel_idP);
exit(1);
ret = 0;
}
@@ -166,8 +166,8 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
switch (channel_idP) {
- case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
- case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
+ case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
+ case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -227,8 +227,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP);
switch (channel_idP) {
- case 1 ... 2: rb = ue->srb[channel_idP - 1]; break;
- case 3 ... 7: rb = ue->drb[channel_idP - 3]; break;
+ case 1 ... 3: rb = ue->srb[channel_idP - 1]; break;
+ case 4 ... 8: rb = ue->drb[channel_idP - 4]; break;
default: rb = NULL; break;
}
@@ -654,7 +654,7 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s)
exit(1);
}
- if (channel_id != drb_id + 2) {
+ if (channel_id != drb_id + 3) {
LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
@@ -737,7 +737,7 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s)
exit(1);
}
- if (channel_id != drb_id + 2) {
+ if (channel_id != drb_id + 3) {
LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
index 464cf3d083..f578faaf38 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h
@@ -28,7 +28,7 @@ typedef void nr_rlc_ue_manager_t;
typedef struct nr_rlc_ue_t {
int rnti;
- nr_rlc_entity_t *srb[2];
+ nr_rlc_entity_t *srb[3];
nr_rlc_entity_t *drb[5];
} nr_rlc_ue_t;
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index 4dacef3dbb..174e07cc33 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -62,15 +62,15 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
if (UL_info->rach_ind.pdu_list[0].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[0].num_preamble==1,
"More than 1 preamble not supported\n");
-
- /*nr_initiate_ra_proc(UL_info->module_id,
+
+ nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[0].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[0].freq_index,
UL_info->rach_ind.pdu_list[0].symbol_index,
- UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance);*/
+ UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance);
}
}
@@ -224,9 +224,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id];
NR_IF_Module_t *ifi = if_inst[module_id];
gNB_MAC_INST *mac = RC.nrmac[module_id];
- LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d crcs:%d]\n",
+
+ LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n",
UL_info->frame,UL_info->slot,
- module_id,CC_id,
+ module_id,CC_id, UL_info->rach_ind.number_of_pdus,
UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
if (nfapi_mode != 1) {
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 64a814bcdb..43f43922a8 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -32,9 +32,9 @@
#include "PHY/defs_nr_UE.h"
#include "NR_IF_Module.h"
-#include "mac_proto.h"
+#include "NR_MAC_UE/mac_proto.h"
#include "assertions.h"
-#include "LAYER2/NR_MAC_UE/mac_extern.h"
+#include "NR_MAC_UE/mac_extern.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
#include "executables/softmodem-common.h"
@@ -93,6 +93,14 @@ int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_n
*/
}
+int8_t handle_rar (nr_downlink_indication_t *dl_info){
+
+ LOG_D(MAC, "handling RAR at MAC layer \n");
+ nr_process_rar (dl_info);
+ return 0;
+
+}
+
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
NR_UE_L2_STATE_t ret;
@@ -105,14 +113,18 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
mac->dl_config_request.number_pdus = 0;
// clean previous FAPI messages
- ret = nr_ue_scheduler(
- ul_info->module_id,
- ul_info->gNB_index,
- ul_info->cc_id,
- ul_info->frame,
- ul_info->slot,
- ul_info->ssb_index,
- 0, 0); // TODO check tx/rx frame/slot is need for NR version
+ ret = nr_ue_scheduler(NULL, ul_info);
+
+ if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra){
+ nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx);
+ if (mac->generate_nr_prach){
+ //uint16_t monitoring_slot_period, monitoring_offset;
+ uint16_t rach_frame = mac->scheduled_response.ul_config->sfn;
+ uint16_t rx_rach_frame = (rach_frame + mac->RA_offset) % MAX_FRAME_NUMBER; // compensate 2 frames offset delay at gNB side
+ uint16_t rach_slot = mac->scheduled_response.ul_config->slot;
+ nr_ue_msg2_scheduler(module_id, rx_rach_frame, rach_slot, &mac->msg2_rx_frame, &mac->msg2_rx_slot);
+ }
+ }
switch(ret){
case UE_CONNECTION_OK:
@@ -127,14 +139,13 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
break;
}
-
mac->if_module->scheduled_response(&mac->scheduled_response);
return 0;
}
int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){
-
+
int32_t i;
uint32_t ret_mask = 0x0;
module_id_t module_id = dl_info->module_id;
@@ -142,132 +153,98 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
- dl_config->number_pdus = 0;
- ul_config->number_pdus = 0;
- //hook up pointers
- mac->scheduled_response.dl_config = dl_config;
- mac->scheduled_response.ul_config = ul_config;
- mac->scheduled_response.tx_request = &mac->tx_request;
- mac->scheduled_response.module_id = dl_info->module_id;
- mac->scheduled_response.CC_id = dl_info->cc_id;
- mac->scheduled_response.frame = dl_info->frame;
- mac->scheduled_response.slot = dl_info->slot;
+ if (!dl_info->dci_ind && !dl_info->rx_ind) {
+ // UL indication to schedule reception DCI reception
+ nr_ue_scheduler(dl_info, NULL);
+ } else {
+ // UL indication after reception of DCI or DL PDU
+ dl_config->number_pdus = 0;
+ ul_config->number_pdus = 0;
+ //hook up pointers
+ mac->scheduled_response.dl_config = dl_config;
+ mac->scheduled_response.ul_config = ul_config;
+ mac->scheduled_response.tx_request = &mac->tx_request;
+ mac->scheduled_response.module_id = dl_info->module_id;
+ mac->scheduled_response.CC_id = dl_info->cc_id;
+ mac->scheduled_response.frame = dl_info->frame;
+ mac->scheduled_response.slot = dl_info->slot;
- if(dl_info->dci_ind != NULL){
- LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
- for(i=0; idci_ind->number_of_dcis; ++i){
- LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
- // fapi_nr_dci_pdu_rel15_t *dci = &dl_info->dci_ind->dci_list[i].dci;
+ if(dl_info->dci_ind != NULL){
+ LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
+ for(i=0; idci_ind->number_of_dcis; ++i){
+ LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
- ret_mask |= (handle_dci(dl_info->module_id,
- dl_info->cc_id,
- dl_info->gNB_index,
- dl_info->dci_ind->dci_list+i)<< FAPI_NR_DCI_IND);
-
- AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" );
- nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response);
-
-
- /*switch((dl_info->dci_ind->dci_list+i)->dci_type){
- case FAPI_NR_DCI_TYPE_0_0:
- case FAPI_NR_DCI_TYPE_0_1:
- case FAPI_NR_DCI_TYPE_1_1:
- case FAPI_NR_DCI_TYPE_2_0:
- case FAPI_NR_DCI_TYPE_2_1:
- case FAPI_NR_DCI_TYPE_2_2:
- case FAPI_NR_DCI_TYPE_2_3:
- AssertFatal(1==0, "Not yet support at this moment!\n");
- break;
-
- case FAPI_NR_DCI_TYPE_1_0:
-
- dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
-
- // mapping into DL_CONFIG_REQ for DL-SCH
- fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
-
- dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = 0x0000; // TX RNTI: UE-spec
- memcpy(dlsch_config_pdu, dci, sizeof(fapi_nr_dci_pdu_rel15_t));
-
- dl_config->number_pdus = dl_config->number_pdus + 1;
-
- ret_mask |= (handle_dci(
- dl_info->module_id,
- dl_info->cc_id,
- dl_info->gNB_index,
- dci,
- (dl_info->dci_ind->dci_list+i)->rnti,
- (dl_info->dci_ind->dci_list+i)->dci_type)) << FAPI_NR_DCI_IND;
-
-
-
- break;
-
- default:
- break;
- }*/
-
- //(dl_info->dci_list+i)->rnti
- }
- }
-
- if(dl_info->rx_ind != NULL){
- LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
- for(i=0; irx_ind->number_pdus; ++i){
- switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
- case FAPI_NR_RX_PDU_TYPE_MIB:
- ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
- (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.pdu,
- (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.additional_bits,
- (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_index,
- (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_length,
- (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;
- LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], MIB case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
- /*ret_mask |= (handle_bcch_bch( dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
- dl_info->rx_ind->rx_indication_body[i].mib_pdu.pdu,
- dl_info->rx_ind->rx_indication_body[i].mib_pdu.additional_bits,
- dl_info->rx_ind->rx_indication_body[i].mib_pdu.ssb_index,
- dl_info->rx_ind->rx_indication_body[i].mib_pdu.ssb_length,
- dl_info->rx_ind->rx_indication_body[i].mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;*/
- break;
- case FAPI_NR_RX_PDU_TYPE_SIB:
- ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
- (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
- (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
- (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length )) << FAPI_NR_RX_PDU_TYPE_SIB;
- break;
- case FAPI_NR_RX_PDU_TYPE_DLSCH:
- // ret_mask |= (0) << FAPI_NR_RX_PDU_TYPE_DLSCH;
- ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
- (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
- (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot, ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
-
- LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], DLSCH case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
-
- /*
- // dl_config structure just stores what was received - not really needed
- dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
- dl_config->number_pdus = dl_config->number_pdus + 1;
- */
-
- /*ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
- dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu,
- dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
-
- */
- break;
- default:
-
- break;
+ ret_mask |= (handle_dci(dl_info->module_id,
+ dl_info->cc_id,
+ dl_info->gNB_index,
+ dl_info->dci_ind->dci_list+i)<< FAPI_NR_DCI_IND);
+ AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" );
+ nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response);
}
}
+
+ if(dl_info->rx_ind != NULL){
+
+ LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
+
+ for(i=0; irx_ind->number_pdus; ++i){
+
+ switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
+
+ case FAPI_NR_RX_PDU_TYPE_MIB:
+ ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
+ (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.pdu,
+ (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.additional_bits,
+ (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_index,
+ (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_length,
+ (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_MIB;
+
+ LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], MIB case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
+
+ break;
+
+ case FAPI_NR_RX_PDU_TYPE_SIB:
+
+ ret_mask |= (handle_bcch_dlsch(dl_info->module_id,
+ dl_info->cc_id, dl_info->gNB_index,
+ (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
+ (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
+ (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_SIB;
+
+ break;
+
+ case FAPI_NR_RX_PDU_TYPE_DLSCH:
+
+ ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
+ dl_info->dci_ind,
+ (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
+ (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length,
+ dl_info->frame,
+ dl_info->slot,
+ ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
+
+ LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], DLSCH case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
+
+ break;
+
+ case FAPI_NR_RX_PDU_TYPE_RAR:
+
+ ret_mask |= (handle_rar(dl_info)) << FAPI_NR_RX_PDU_TYPE_RAR;
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ //clean up nr_downlink_indication_t *dl_info
+ dl_info->rx_ind = NULL;
+ dl_info->dci_ind = NULL;
+
}
-
- //clean up nr_downlink_indication_t *dl_info
- dl_info->rx_ind = NULL;
- dl_info->dci_ind = NULL;
-
return 0;
}
@@ -305,7 +282,12 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) {
dl_config->sfn=UE_mac->dl_config_request.sfn;
dl_config->slot=UE_mac->dl_config_request.slot;
dl_config->number_pdus=0;
-
- ue_dci_configuration(UE_mac,dl_config,dcireq->frame,dcireq->slot);
+
+ printf(" UE_mac->dl_config_request.slot %d VS dcireq->slot %d \n", UE_mac->dl_config_request.slot, dcireq->slot);
+
+ LOG_D(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot);
+
+ ue_dci_configuration(UE_mac, dl_config, dcireq->frame, dcireq->slot);
+
return 0;
}
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
index 0784e71584..df2d78f0cb 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -72,7 +72,8 @@ typedef struct {
/// NR UE FAPI-like P7 message, direction: L1 to L2
/// data reception indication structure
fapi_nr_rx_indication_t *rx_ind;
-
+ /// ssb_index, if ssb is not present in current TTI, value set to -1
+ int ssb_index;
/// dci reception indication structure
fapi_nr_dci_indication_t *dci_ind;
@@ -87,11 +88,13 @@ typedef struct {
/// component carrier id
int cc_id;
/// frame
- frame_t frame;
- /// slot
- uint32_t slot;
- /// ssb_index, if ssb is not present in current TTI, thie value set to -1
- int ssb_index;
+ frame_t frame_rx;
+ /// slot rx
+ uint32_t slot_rx;
+ /// frame tx
+ frame_t frame_tx;
+ /// slot tx
+ uint32_t slot_tx;
/// dci reception indication structure
fapi_nr_dci_indication_t *dci_ind;
} nr_uplink_indication_t;
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index f050733a13..52b06b9f11 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -382,6 +382,7 @@ typedef enum e_rab_satus_e {
E_RAB_STATUS_DONE, // from the eNB perspective
E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
E_RAB_STATUS_REESTABLISHED, // after HO
+ E_RAB_STATUS_TOMODIFY, // ENDC NSA
E_RAB_STATUS_FAILED,
E_RAB_STATUS_TORELEASE // to release DRB between eNB and UE
} e_rab_status_t;
@@ -613,6 +614,7 @@ typedef struct eNB_RRC_UE_s {
/* Number of e_rab to be modified in the list */
uint8_t nb_of_modify_e_rabs;
uint8_t nb_of_failed_e_rabs;
+ uint8_t nb_of_modify_endc_e_rabs;
e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
/* list of e_rab to be setup by RRC layers */
e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
@@ -627,6 +629,10 @@ typedef struct eNB_RRC_UE_s {
uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB];
rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB];
+ // LG: For GTPV1 TUNNELS ENDC
+ uint32_t gnb_gtp_endc_teid[S1AP_MAX_E_RAB];
+ transport_layer_addr_t gnb_gtp_endc_addrs[S1AP_MAX_E_RAB];
+ rb_id_t gnb_gtp_endc_ebi[S1AP_MAX_E_RAB];
/* Total number of e_rab already setup in the list */
uint8_t nb_x2u_e_rabs;
// LG: For GTPV1 TUNNELS(X2U)
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 5965e51720..ba6b2c41c1 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -4398,6 +4398,17 @@ rrc_eNB_process_MeasurementReport(
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti;
+ //For the moment we have a single E-RAB which will be the one to be added to the gNB
+ //Not sure how to select bearers to be added if there are multiple.
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1;
+ for (int e_rab=0; e_rab < X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded; e_rab++){
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].gtp_teid = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid;
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = 1;
+ memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].sgw_addr,
+ &ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr,
+ sizeof(transport_layer_addr_t));
+ }
LOG_I(RRC,
"[eNB %d] frame %d subframe %d: UE rnti %x switching to NSA mode\n",
ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rnti);
@@ -7537,6 +7548,41 @@ rrc_eNB_decode_dcch(
}
ue_context_p->ue_context.reestablishment_xid = -1;
+
+ //Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete
+ //including NR specific elements. Not sure if this is the correct one and the correct placement
+ /*if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->
+ scg_ConfigResponseNR_r15->buf!=NULL){
+ //Trigger E-RAB Modification Indication
+ rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p);
+ }*/
+
+ if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension!=NULL){
+ if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension->nonCriticalExtension!=NULL){
+ if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
+ if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
+ if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
+ if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){
+ if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.
+ nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
+ ->scg_ConfigResponseNR_r15!=NULL){
+ /*Trigger E-RAB Modification Indication */
+ rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
} else {
dedicated_DRB = 1;
ue_context_p->ue_context.Status = RRC_RECONFIGURED;
@@ -8708,6 +8754,27 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP,
ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti);
+ ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded;
+
+ int j=0;
+ while(j < m->nb_e_rabs_admitted_tobeadded){
+ for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++){
+ //Update ue_context information with gNB's address and new GTP tunnel ID
+ if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id){
+ memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer,
+ m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer,
+ m->e_rabs_admitted_tobeadded[j].gnb_addr.length);
+ ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length;
+ ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid;
+ ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY;
+ break;
+ }
+ }
+ j++;
+ }
+
+
+
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
0,
ENB_FLAG_YES,
diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
index 6bbdef181b..1025d46f62 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
@@ -92,6 +92,7 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
}
}
+
//------------------------------------------------------------------------------
boolean_t
gtpv_data_req(
diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
index 00c7490359..6318ed4927 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
@@ -43,6 +43,13 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
uint8_t *inde_list
);
+int
+rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
+ const protocol_ctxt_t *const ctxt_pP,
+ const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
+ uint8_t *inde_list
+);
+
/*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP)
*\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels.
*\param module_id Instance ID of eNB.
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 59998cebcc..27a442ed05 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -2284,3 +2284,75 @@ int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id)
}*/
return 0;
}
+
+
+int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP,
+ rrc_eNB_ue_context_t *const ue_context_pP) {
+ MessageDef *msg_p = NULL;
+ int e_rab = 0;
+ int e_rab_modify_index = 0;
+ int e_rab_notmodify_index = 0;
+
+ uint8_t inde_list[ue_context_pP->ue_context.nb_of_e_rabs];
+ memset(inde_list, 0, ue_context_pP->ue_context.nb_of_e_rabs*sizeof(uint8_t));
+
+ msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFICATION_IND);
+
+
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id;
+
+ LOG_I (RRC,"E-RAB modification indication: nb nb_of_e_rabs %u status %u\n",
+ ue_context_pP->ue_context.nb_of_e_rabs,
+ ue_context_pP->ue_context.e_rab[e_rab].status);
+
+ if (ue_context_pP->ue_context.nb_of_modify_endc_e_rabs > 0){
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified = ue_context_pP->ue_context.nb_of_modify_endc_e_rabs;
+ for (e_rab = 0; e_rab < ue_context_pP->ue_context.setup_e_rabs ; e_rab++) {
+ //Add E-RAB in the list of E-RABs to be modified
+ if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_TOMODIFY) {
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
+ memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.buffer,
+ ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer,
+ ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length);
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length;
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab];
+ e_rab_modify_index++;
+ }
+ //Add E-RAB in the list of E-RABs NOT to be modified
+ else{
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
+ memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.buffer,
+ ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer,
+ ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length);
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length;
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab];
+ e_rab_notmodify_index++;
+ }
+ }
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_nottobemodified = e_rab_notmodify_index;
+ }
+
+ if (e_rab_modify_index > 0) {
+ LOG_I(RRC,"S1AP_E_RAB_MODIFICATION_IND: sending the message: nb_of_erabstobemodified %d, total e_rabs %d, index %d\n",
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified, ue_context_pP->ue_context.setup_e_rabs, e_rab);
+ MSC_LOG_TX_MESSAGE(
+ MSC_RRC_ENB,
+ MSC_S1AP_ENB,
+ (const char *)&S1AP_E_RAB_MODIFICATION_IND (msg_p),
+ sizeof(s1ap_e_rab_modification_ind_t),
+ MSC_AS_TIME_FMT" E RAB MODIFICATION IND UE %X eNB_ue_s1ap_id %u e_rabs:%u succ",
+ MSC_AS_TIME_ARGS(ctxt_pP),
+ ue_context_pP->ue_id_rnti,
+ S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id,
+ e_rab_modify_index);
+ itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
+ } else {
+ itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
+ }
+
+ return 0;
+}
+
+
+
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h
index e5ff9c27d6..a55d17bfd1 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.h
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h
@@ -285,4 +285,6 @@ int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, r
int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id);
+int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP);
+
#endif /* RRC_ENB_S1AP_H_ */
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 1e8e45ef4d..0905f6d7de 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -51,9 +51,8 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
uint8_t *const buffer_pP ){
asn_enc_rval_t enc_rval;
- //SRB_INFO *Srb_info;
- //uint8_t Sdu_size = 0;
- uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
+ uint8_t Sdu_size = 0;
+ uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
#ifdef DEBUG_RRC
LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
@@ -62,11 +61,15 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
gNB_RRC_INST *rrc;
rrc_gNB_carrier_data_t *carrier;
NR_BCCH_BCH_Message_t *mib;
+ NR_SRB_INFO * srb_info;
+ char payload_size, *payload_pP;
rrc = RC.nrrrc[Mod_idP];
carrier = &rrc->carrier;
mib = &carrier->mib;
+ srb_info = &carrier->Srb0;
+ /* MIBCH */
if( (Srb_id & RAB_OFFSET ) == MIBCH) {
mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2;
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message,
@@ -84,10 +87,31 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return(3);
}
-//BCCH SIB1 SIBs
+ /* TODO BCCH SIB1 SIBs */
-//CCCH
+ /* CCCH */
+ if( (Srb_id & RAB_OFFSET ) == CCCH) {
+ //struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
+ //if (ue_context_p == NULL) return(0);
+ //eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
+ LOG_D(RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
+
+ // srb_info=&ue_p->Srb0;
+
+ payload_size = srb_info->Tx_buffer.payload_size;
+
+ // check if data is there for MAC
+ if (payload_size > 0) {
+ payload_pP = srb_info->Tx_buffer.Payload;
+ LOG_D(RRC,"[gNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n", Mod_idP, srb_info, payload_size, buffer_pP, payload_pP);
+ // Fill buffer
+ memcpy((void *)buffer_pP, (void*)payload_pP, payload_size);
+ Sdu_size = payload_size;
+ srb_info->Tx_buffer.payload_size = 0;
+ }
+ return Sdu_size;
+ }
return(0);
-}
+}
\ No newline at end of file
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 02b4154c41..eeb16c3087 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -319,9 +319,10 @@ typedef struct gNB_RRC_UE_s {
uint8_t nb_release_of_e_rabs;
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
// LG: For GTPV1 TUNNELS
- uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
- transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB];
- rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB];
+ uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB];
+ transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB];
+ rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB];
+
uint32_t ul_failure_timer;
uint32_t ue_release_timer;
uint32_t ue_release_timer_thres;
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 5770b80595..fd766f7e12 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -65,9 +65,9 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP);
-void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList);
+void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m);
-void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p);
+void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
NR_CellGroupConfig_t *secondaryCellGroup,
@@ -89,7 +89,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
NR_RRCReconfiguration_t *reconfig,
NR_RadioBearerConfig_t *rbconfig);
-int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo);
+int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 5ece5f9169..a2e66fa93e 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -200,12 +200,12 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
rrc->carrier.pdsch_AntennaPorts,
(NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
0,
- 0,
+ 0, // WIP hardcoded rnti
(NR_CellGroupConfig_t *)NULL
);
- if (get_softmodem_params()->phy_test > 0) {
+ if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
// This is for phytest only, emulate first X2 message if uecap.raw file is present
FILE *fd;
@@ -246,13 +246,13 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo,
(const char *)buffer,
(enc_rval.encoded+7)>>3);
- parse_CG_ConfigInfo(rrc,CG_ConfigInfo);
+ parse_CG_ConfigInfo(rrc,CG_ConfigInfo,NULL);
}
else {
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
- rrc_add_nsa_user(rrc,ue_context_p);
+ rrc_add_nsa_user(rrc,ue_context_p,NULL);
}
}
}
@@ -304,12 +304,6 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x
(uint8_t *)m->rrc_buffer,
(int) m->rrc_buffer_size);//m->rrc_buffer_size);
-/* asn_dec_rval_t dec_rval = uper_decode( NULL,
- &asn_DEF_LTE_UL_DCCH_Message,
- (void **)<E_UL_DCCH_Message,
- (uint8_t *)m->rrc_buffer,
- (int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size);
-*/
gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP];
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
@@ -335,7 +329,7 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x
OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo,
(const char *)m->rrc_buffer,
(enc_rval.encoded+7)>>3);
- parse_CG_ConfigInfo(rrc,CG_ConfigInfo);
+ parse_CG_ConfigInfo(rrc,CG_ConfigInfo,m);
}
diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c
new file mode 100644
index 0000000000..9ab1bbf43a
--- /dev/null
+++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c
@@ -0,0 +1,94 @@
+/*
+ * 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 rrc_gNB_GTPV1U.c
+ * \brief rrc GTPV1U procedures for gNB
+ * \author Lionel GAUTHIER, Panos MATZAKOS
+ * \version 1.0
+ * \company Eurecom
+ * \email: lionel.gauthier@eurecom.fr, panagiotis.matzakos@eurecom.fr
+ */
+
+# include "rrc_defs.h"
+# include "rrc_extern.h"
+# include "RRC/LTE/MESSAGES/asn1_msg.h"
+# include "rrc_eNB_GTPV1U.h"
+# include "rrc_eNB_UE_context.h"
+# include "msc.h"
+# include "openair2/RRC/NR/rrc_gNB_UE_context.h"
+
+//# if defined(ENABLE_ITTI)
+# include "asn1_conversions.h"
+# include "intertask_interface.h"
+//#endif
+
+# include "common/ran_context.h"
+
+extern RAN_CONTEXT_t RC;
+
+int
+rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
+ const protocol_ctxt_t *const ctxt_pP,
+ const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
+ uint8_t *inde_list
+) {
+ rnti_t rnti;
+ int i;
+ struct rrc_gNB_ue_context_s *ue_context_p = NULL;
+
+ if (create_tunnel_resp_pP) {
+ LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
+ PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+ create_tunnel_resp_pP->num_tunnels);
+ rnti = create_tunnel_resp_pP->rnti;
+ ue_context_p = rrc_gNB_get_ue_context(
+ RC.nrrrc[ctxt_pP->module_id],
+ ctxt_pP->rnti);
+
+ for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
+ ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
+ ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
+ ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
+ LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
+ PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+ create_tunnel_resp_pP->enb_S1u_teid[i],
+ ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]],
+ inde_list[i],
+ i,
+ create_tunnel_resp_pP->eps_bearer_id[i],
+ create_tunnel_resp_pP->enb_addr.length);
+ }
+
+ MSC_LOG_RX_MESSAGE(
+ MSC_RRC_ENB,
+ MSC_GTPU_ENB,
+ NULL,0,
+ MSC_AS_TIME_FMT" CREATE_TUNNEL_RESP RNTI %"PRIx16" ntuns %u ebid %u enb-s1u teid %u",
+ 0,0,rnti,
+ create_tunnel_resp_pP->num_tunnels,
+ ue_context_p->ue_context.gnb_gtp_ebi[0],
+ ue_context_p->ue_context.gnb_gtp_teid[0]);
+ (void)rnti; /* avoid gcc warning "set but not used" */
+ return 0;
+ } else {
+ return -1;
+ }
+}
diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.h b/openair2/RRC/NR/rrc_gNB_GTPV1U.h
new file mode 100644
index 0000000000..caff825a7a
--- /dev/null
+++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.h
@@ -0,0 +1,39 @@
+/*
+ * 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 rrc_gNB_GTPV1U.h
+ * \brief rrc GTPV1U procedures for gNB
+ * \author Lionel GAUTHIER, Panos MATZAKOS
+ * \version 1.0
+ * \company Eurecom
+ * \email: lionel.gauthier@eurecom.fr, panagiotis.matzakos@eurecom.fr
+ */
+
+#ifndef RRC_GNB_GTPV1U_H_
+#define RRC_GNB_GTPV1U_H_
+
+
+int
+rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
+ const protocol_ctxt_t *const ctxt_pP,
+ const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
+ uint8_t *inde_list
+);
diff --git a/openair2/RRC/NR/rrc_gNB_internode.c b/openair2/RRC/NR/rrc_gNB_internode.c
index 581015db56..916f4d63da 100644
--- a/openair2/RRC/NR/rrc_gNB_internode.c
+++ b/openair2/RRC/NR/rrc_gNB_internode.c
@@ -38,7 +38,7 @@
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
-int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) {
+int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m) {
if (CG_ConfigInfo->criticalExtensions.present == NR_CG_ConfigInfo__criticalExtensions_PR_c1) {
if (CG_ConfigInfo->criticalExtensions.choice.c1) {
@@ -56,7 +56,7 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) {
AssertFatal(1==0,"[InterNode] Failed to decode NR_UE_CapabilityRAT_ContainerList (%zu bits), size of OCTET_STRING %lu\n",
dec_rval.consumed, cg_ConfigInfo->ue_CapabilityInfo->size);
}
- rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList);
+ rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList, m);
}
if (cg_ConfigInfo->candidateCellInfoListMN) AssertFatal(1==0,"Can't handle candidateCellInfoListMN yet\n");
}
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index d4647511a9..70bd150bd4 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -37,13 +37,15 @@
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
-void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList) {
+void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m) {
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
- OCTET_STRING_t *ueCapabilityRAT_Container_nr=NULL;
- OCTET_STRING_t *ueCapabilityRAT_Container_MRDC=NULL;
- int list_size=0;
+ OCTET_STRING_t *ueCapabilityRAT_Container_nr = NULL;
+ OCTET_STRING_t *ueCapabilityRAT_Container_MRDC = NULL;
+ int list_size;
+ asn_dec_rval_t dec_rval;
AssertFatal(UE_CapabilityRAT_ContainerList!=NULL,"UE_CapabilityRAT_ContainerList is null\n");
AssertFatal((list_size=UE_CapabilityRAT_ContainerList->list.count) >= 2, "UE_CapabilityRAT_ContainerList->list.size %d < 2\n",UE_CapabilityRAT_ContainerList->list.count);
for (int i=0;ilist.array[i]->rat_Type == LTE_RAT_Type_eutra_nr) ueCapabilityRAT_Container_MRDC = &UE_CapabilityRAT_ContainerList->list.array[i]->ueCapabilityRAT_Container;
}
- AssertFatal(ueCapabilityRAT_Container_nr!=NULL,"ueCapabilityRAT_Container_nr is NULL\n");
- AssertFatal(ueCapabilityRAT_Container_MRDC!=NULL,"ueCapabilityRAT_Container_MRDC is NULL\n");
// decode and store capabilities
ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
-
- asn_dec_rval_t dec_rval = uper_decode(NULL,
- &asn_DEF_NR_UE_NR_Capability,
- (void **)&ue_context_p->ue_context.UE_Capability_nr,
- ueCapabilityRAT_Container_nr->buf,
- ueCapabilityRAT_Container_nr->size, 0, 0);
- if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
- LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size);
- ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,
- ue_context_p->ue_context.UE_Capability_nr);
- ue_context_p->ue_context.UE_Capability_nr = 0;
- AssertFatal(1==0,"exiting\n");
+ if (ueCapabilityRAT_Container_nr != NULL) {
+ dec_rval = uper_decode(NULL,
+ &asn_DEF_NR_UE_NR_Capability,
+ (void **)&ue_context_p->ue_context.UE_Capability_nr,
+ ueCapabilityRAT_Container_nr->buf,
+ ueCapabilityRAT_Container_nr->size, 0, 0);
+
+ if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
+ LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size);
+ ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,
+ ue_context_p->ue_context.UE_Capability_nr);
+ ue_context_p->ue_context.UE_Capability_nr = 0;
+ AssertFatal(1==0,"exiting\n");
+ }
}
- dec_rval = uper_decode(NULL,
- &asn_DEF_NR_UE_MRDC_Capability,
- (void **)&ue_context_p->ue_context.UE_Capability_MRDC,
- ueCapabilityRAT_Container_MRDC->buf,
- ueCapabilityRAT_Container_MRDC->size, 0, 0);
+ if (ueCapabilityRAT_Container_MRDC != NULL) {
+ dec_rval = uper_decode(NULL,
+ &asn_DEF_NR_UE_MRDC_Capability,
+ (void **)&ue_context_p->ue_context.UE_Capability_MRDC,
+ ueCapabilityRAT_Container_MRDC->buf,
+ ueCapabilityRAT_Container_MRDC->size, 0, 0);
- if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
- LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed);
- ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,
- ue_context_p->ue_context.UE_Capability_MRDC);
- ue_context_p->ue_context.UE_Capability_MRDC = 0;
- AssertFatal(1==0,"exiting\n");
+ if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
+ LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed);
+ ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,
+ ue_context_p->ue_context.UE_Capability_MRDC);
+ ue_context_p->ue_context.UE_Capability_MRDC = 0;
+ AssertFatal(1==0,"exiting\n");
+ }
}
// dump ue_capabilities
- if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) {
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
}
- if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) {
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
}
- rrc_add_nsa_user(rrc,ue_context_p);
+ rrc_add_nsa_user(rrc,ue_context_p, m);
}
-void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p) {
+void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) {
// generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331)
@@ -105,6 +109,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
MessageDef *msg;
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
+ gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
+ gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
+ protocol_ctxt_t ctxt;
// NR RRCReconfiguration
@@ -132,6 +139,77 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
memset((void*)CG_Config,0,sizeof(*CG_Config));
__attribute__((unused))int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
+ if(m!=NULL){
+ uint8_t inde_list[m->nb_e_rabs_tobeadded];
+ memset(inde_list, 0, m->nb_e_rabs_tobeadded*sizeof(uint8_t));
+
+ if (m->nb_e_rabs_tobeadded>0){
+ for (int i=0; inb_e_rabs_tobeadded; i++){
+ // Add the new E-RABs at the corresponding rrc ue context of the gNB
+ ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
+ ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
+ memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
+ ue_context_p->ue_context.nb_of_e_rabs++;
+ //Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW
+ create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
+ create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid;
+ memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
+ inde_list[i] = i;
+ LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
+ i,
+ create_tunnel_req.sgw_addr[i].buffer[0],
+ create_tunnel_req.sgw_addr[i].buffer[1],
+ create_tunnel_req.sgw_addr[i].buffer[2],
+ create_tunnel_req.sgw_addr[i].buffer[3],
+ create_tunnel_req.sgw_addr[i].length,
+ create_tunnel_req.sgw_S1u_teid[i]);
+ }
+ //PM: Is this where we should extract the rnti from?
+ create_tunnel_req.rnti = ue_context_p->ue_id_rnti;
+ create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded;
+ RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p);
+
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id);
+ gtpv1u_create_s1u_tunnel(
+ ctxt.instance,
+ &create_tunnel_req,
+ &create_tunnel_resp);
+ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
+ &ctxt,
+ &create_tunnel_resp,
+ &inde_list[0]);
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded;
+ for(int i=0; iue_context.nb_of_e_rabs; i++){
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i];
+ memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t));
+
+ //The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length = create_tunnel_resp.enb_addr.length*8;
+
+ LOG_I(RRC,"S1-U create_tunnel_resp tunnel: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n",
+ i,
+ create_tunnel_resp.enb_addr.buffer[0],
+ create_tunnel_resp.enb_addr.buffer[1],
+ create_tunnel_resp.enb_addr.buffer[2],
+ create_tunnel_resp.enb_addr.buffer[3],
+ create_tunnel_resp.enb_addr.length,
+ create_tunnel_resp.enb_S1u_teid[i]);
+ LOG_I(RRC,"X2AP sGNB Addition Request: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n",
+ i,
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[0],
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[1],
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[2],
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[3],
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length,
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid);
+ }
+ }
+ else
+ LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n");
+ }
+
+
//X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size
// Send to X2 entity to transport to MeNB
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config,
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 1df17a19aa..03c5e6ec95 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -155,6 +155,26 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = NULL;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->ext1 = NULL;
+ /* contention free ra */
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
+ memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric, &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
+ //secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
+ //*secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= NULL;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
+ struct NR_CFRA_SSB_Resource *ssbElem = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
+ ssbElem->ssb = 0;
+ ssbElem->ra_PreambleIndex= 63;
+ ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem);
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
+
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants));
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup));
@@ -354,7 +374,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL;
- secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType0;
+ secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList=NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->pdsch_AggregationFactor=NULL;
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternToAddModList=NULL;
@@ -407,17 +427,45 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Common->pdcch_ConfigCommon->present = NR_SetupRelease_PDCCH_ConfigCommon_PR_setup;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup = calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup));
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL;
- bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=NULL;
- bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL;
+ bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet));
+ NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset));
+ coreset->controlResourceSetId=1;
+ // frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B,
+ coreset->frequencyDomainResources.buf = calloc(1,6);
+ coreset->frequencyDomainResources.buf[0] = 0xff;
+ coreset->frequencyDomainResources.buf[1] = 0xff;
+ coreset->frequencyDomainResources.buf[2] = 0;
+ coreset->frequencyDomainResources.buf[3] = 0;
+ coreset->frequencyDomainResources.buf[4] = 0;
+ coreset->frequencyDomainResources.buf[5] = 0;
+ coreset->frequencyDomainResources.size = 6;
+ coreset->frequencyDomainResources.bits_unused = 3;
+ coreset->duration=1;
+ coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved;
+ coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
+
+ coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList));
+ NR_TCI_StateId_t *tci[8];
+ for (int i=0;i<8;i++) {
+ tci[i]=calloc(1,sizeof(*tci[i]));
+ *tci[i] = i;
+ ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]);
+ }
+ coreset->tci_StatesPDCCH_ToReleaseList = NULL;
+ coreset->tci_PresentInDCI = NULL;
+ coreset->pdcch_DMRS_ScramblingID = NULL;
+
+ bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset;
+
+ bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL;
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=NULL;
-
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList));
NR_SearchSpace_t *ss=calloc(1,sizeof(*ss));
ss->searchSpaceId = 1;
ss->controlResourceSetId=calloc(1,sizeof(*ss->controlResourceSetId));
- *ss->controlResourceSetId=0;
+ *ss->controlResourceSetId=1;
ss->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss->monitoringSlotPeriodicityAndOffset));
ss->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
ss->duration=NULL;
@@ -474,64 +522,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Dedicated->pdcch_Config->present = NR_SetupRelease_PDCCH_Config_PR_setup;
bwp->bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup));
bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList));
- NR_ControlResourceSet_t *coreset0 = calloc(1,sizeof(*coreset0));
- coreset0->controlResourceSetId=1;
- // frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B,
- coreset0->frequencyDomainResources.buf = calloc(1,6);
- coreset0->frequencyDomainResources.buf[0] = 0xff;
- coreset0->frequencyDomainResources.buf[1] = 0xff;
- coreset0->frequencyDomainResources.buf[2] = 0;
- coreset0->frequencyDomainResources.buf[3] = 0;
- coreset0->frequencyDomainResources.buf[4] = 0;
- coreset0->frequencyDomainResources.buf[5] = 0;
- coreset0->frequencyDomainResources.size = 6;
- coreset0->frequencyDomainResources.bits_unused = 3;
- coreset0->duration=1;
- coreset0->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved;
- coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
- coreset0->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList));
- NR_TCI_StateId_t *tci[8];
- for (int i=0;i<8;i++) {
- tci[i]=calloc(1,sizeof(*tci[i]));
- *tci[i] = i;
- ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
- }
- coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
- coreset0->tci_PresentInDCI = NULL;
- coreset0->pdcch_DMRS_ScramblingID = NULL;
ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list,
- coreset0);
+ coreset);
bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList));
- NR_SearchSpace_t *ss3 = calloc(1,sizeof(*ss3));
+
NR_SearchSpace_t *ss2 = calloc(1,sizeof(*ss2));
- ss3->searchSpaceId=3;
- ss3->controlResourceSetId=calloc(1,sizeof(*ss3->controlResourceSetId));
- *ss3->controlResourceSetId=1;
- ss3->monitoringSlotPeriodicityAndOffset=calloc(1,sizeof(*ss3->monitoringSlotPeriodicityAndOffset));
- ss3->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
- ss3->monitoringSlotPeriodicityAndOffset->choice.sl1=(NULL_t)0;
- ss3->duration=NULL;
- ss3->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss3->monitoringSymbolsWithinSlot));
- ss3->monitoringSymbolsWithinSlot->buf = calloc(1,2);
- ss3->monitoringSymbolsWithinSlot->size = 2;
- ss3->monitoringSymbolsWithinSlot->bits_unused = 2;
- ss3->monitoringSymbolsWithinSlot->buf[0]=0xc0;
- ss3->monitoringSymbolsWithinSlot->buf[1]=0x0;
- ss3->nrofCandidates=calloc(1,sizeof(*ss3->nrofCandidates));
- ss3->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
- ss3->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
- ss3->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
- ss3->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
- ss3->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
- ss3->searchSpaceType=calloc(1,sizeof(*ss3->searchSpaceType));
- ss3->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
- ss3->searchSpaceType->choice.common = calloc(1,sizeof(*ss3->searchSpaceType->choice.common));
- ss3->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0=calloc(1,sizeof(*ss3->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
- ss3->searchSpaceType->choice.common->dci_Format2_0=NULL;
- ss3->searchSpaceType->choice.common->dci_Format2_2=NULL;
- ss3->searchSpaceType->choice.common->dci_Format2_3=NULL;
ss2->searchSpaceId=2;
ss2->controlResourceSetId=calloc(1,sizeof(*ss2->controlResourceSetId));
@@ -557,8 +554,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ss2->searchSpaceType->choice.ue_Specific = calloc(1,sizeof(*ss2->searchSpaceType->choice.ue_Specific));
ss2->searchSpaceType->choice.ue_Specific->dci_Formats=NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0;
- ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list,
- ss3);
ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list,
ss2);
@@ -747,7 +742,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL;
- bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType0;
+ bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_AggregationFactor=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternToAddModList=NULL;
@@ -773,7 +768,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL;
- bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType0;
+ bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_AggregationFactor=NULL;
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternToAddModList=NULL;
diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c
index cb8ded1971..08976522b0 100644
--- a/openair2/RRC/NR_UE/L2_interface_ue.c
+++ b/openair2/RRC/NR_UE/L2_interface_ue.c
@@ -56,4 +56,15 @@ nr_mac_rrc_data_ind_ue(
return(0);
+}
+
+int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
+ const int CC_id,
+ const frame_t frameP,
+ const rb_id_t Srb_id,
+ uint8_t *const buffer_pP ){
+
+ // todo
+
+ return 0;
}
\ No newline at end of file
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index 87e899845e..44215df218 100755
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -42,7 +42,7 @@
#include "rrc_defs.h"
#include "rrc_proto.h"
#include "rrc_vars.h"
-#include "mac_proto.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "executables/softmodem-common.h"
@@ -319,7 +319,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations);
RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
- if (get_softmodem_params()->phy_test==1) {
+ if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
// read in files for RRCReconfiguration and RBconfig
FILE *fd;
char filename[1024];
diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h
index cb1207757d..6481fb0cea 100644
--- a/openair2/RRC/NR_UE/rrc_defs.h
+++ b/openair2/RRC/NR_UE/rrc_defs.h
@@ -39,8 +39,8 @@
#include "platform_types.h"
-#include "LAYER2/NR_MAC_UE/mac.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
+#include "NR_MAC_UE/mac.h"
+#include "NR_MAC_COMMON/nr_mac.h"
#include "rrc_list.h"
#include "NR_asn_constant.h"
#include "NR_MeasConfig.h"
diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h
index 6e0d0a10de..7bc7e4b90c 100644
--- a/openair2/RRC/NR_UE/rrc_proto.h
+++ b/openair2/RRC/NR_UE/rrc_proto.h
@@ -102,6 +102,18 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const ui
\param pdu_len data length of pdu*/
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len);
+/**\brief
+ \param module_id module id
+ \param CC_id component carrier id
+ \param frame_t frameP
+ \param rb_id_t SRB id
+ \param buffer_pP pointer to buffer*/
+int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
+ const int CC_id,
+ const frame_t frameP,
+ const rb_id_t Srb_id,
+ uint8_t *const buffer_pP);
+
/** @}*/
#endif
diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c
index b297c96e56..debe5e0712 100644
--- a/openair2/X2AP/x2ap_eNB.c
+++ b/openair2/X2AP/x2ap_eNB.c
@@ -359,7 +359,7 @@ void x2ap_eNB_handle_sctp_init_msg_multi_cnf(
* Failure means multi_sd < 0.
*/
if (instance->multi_sd < 0) {
- X2AP_ERROR("Error: be sure to properly configure X2 in your configuration file.\n");
+ X2AP_ERROR("Error: be sure to properly configure X22 in your configuration file.\n");
DevAssert(instance->multi_sd >= 0);
}
@@ -474,7 +474,7 @@ void x2ap_eNB_handle_sgNB_add_req(instance_t instance,
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1);
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE);
- x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data, ue_id);
+ x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data, ue_id);
}
static
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index 0aeabce0d2..0478448070 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -1496,7 +1496,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
}
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
- x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id)
+ x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBAdditionRequest_t *out;
@@ -1516,8 +1516,6 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
int uEaggregateMaximumBitRateDownlink = 100000000;
int uEaggregateMaximumBitRateUplink = 100000000;
int e_rabs_tobeadded = 1;
- int e_RAB_ID = 1;
- int drb_ID = 2;
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
@@ -1527,9 +1525,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY;
e_rab_tobe_added_t e_MCG_rabs_tobeadded;
e_MCG_rabs_tobeadded.gtp_teid = 0;
- e_MCG_rabs_tobeadded.eNB_addr.length = 24;
+ e_MCG_rabs_tobeadded.sgw_addr.length = 24;
uint8_t buf[20] = { 0 };
- memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t));
+ memcpy(e_MCG_rabs_tobeadded.sgw_addr.buffer, buf, 20*sizeof(uint8_t));
FILE *fd;
fd = fopen("../../../executables/uecap.raw","r");
@@ -1614,8 +1612,8 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item;
e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item;
{
- e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID;
- e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
+ e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].drb_ID;
+ e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].e_rab_id;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
@@ -1628,14 +1626,14 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = priority_level;
//Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case
- INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID);
- e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = e_MCG_rabs_tobeadded.eNB_addr.length/8;
- e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_MCG_rabs_tobeadded.eNB_addr.length%8;
+ INT32_TO_OCTET_STRING(x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID);
+ e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length/8;
+ e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length%8;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf =
calloc(1, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
memcpy (e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
- e_MCG_rabs_tobeadded.eNB_addr.buffer,
+ x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.buffer,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
}
@@ -1696,8 +1694,8 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
//uint8_t SgNBSecurityKey[32] = { 0 };
//int uEaggregateMaximumBitRateDownlink = 100000000;
//int uEaggregateMaximumBitRateUplink = 100000000;
+
int e_rabs_admitted_tobeadded = 1;
- int e_RAB_ID = 1;
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
@@ -1748,21 +1746,21 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item = &e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
{
- e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
+ e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].e_rab_id;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent;
- INT32_TO_OCTET_STRING(e_SCG_rabs_tobeadded.gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID);
- e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = e_SCG_rabs_tobeadded.eNB_addr.length/8;
- e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_SCG_rabs_tobeadded.eNB_addr.length%8;
+ INT32_TO_OCTET_STRING(x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID);
+ e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.length/8;
+ e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.length%8;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf =
calloc(1, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
memcpy (e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
- e_SCG_rabs_tobeadded.eNB_addr.buffer,
+ x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.buffer,
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
}
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h
index 114ed84a68..3dfccc0e52 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.h
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.h
@@ -70,7 +70,7 @@ int x2ap_gNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2a
int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
-int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id);
+int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id);
int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id);
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index afaae1756d..e144eda435 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -1749,13 +1749,22 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel;
- memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.buffer,
+ memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
- X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.length =
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.length =
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
+LOG_I(RRC,"x2u tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
+ i,
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[0],
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[1],
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[2],
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[3],
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.length,
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid);
+
OCTET_STRING_TO_INT32(&e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID,
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid);
}
@@ -1771,13 +1780,12 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer, true);
- X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
- //X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
- if (container->size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s
- { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
- memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size);
- X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size;
+ if (ie->value.choice.MeNBtoSgNBContainer.size > 8192 )
+ { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
+
+ memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size);
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size;
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
@@ -1891,10 +1899,10 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->e_RAB_ID ;
if(e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
- memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.buffer,
+ memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer,
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
- X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.length =
+ X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length =
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
OCTET_STRING_TO_INT32(&e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID,
@@ -1963,7 +1971,7 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
- //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
+ //Allocate an ITTI X2AP_sGNB_reconfiguration_complete message
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE);
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index f15f295548..f095cce67d 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -943,6 +943,8 @@ gtpv1u_create_s1u_tunnel(
memcpy(&create_tunnel_resp_pP->enb_addr.buffer,
&RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up,
sizeof (in_addr_t));
+
+ LOG_I(GTPU,"Configured GTPu address : %x\n",RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
create_tunnel_resp_pP->enb_addr.length = sizeof (in_addr_t);
addrs_length_in_bytes = create_tunnel_req_pP->sgw_addr[i].length / 8;
AssertFatal((addrs_length_in_bytes == 4) ||
@@ -971,6 +973,15 @@ gtpv1u_create_s1u_tunnel(
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_sgw = create_tunnel_req_pP->sgw_S1u_teid[i];
gtpv1u_ue_data_p->num_bearers++;
create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_teid;
+
+ LOG_I(GTPU,"Copied to create_tunnel_resp tunnel: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n",
+ i,
+ create_tunnel_resp_pP->enb_addr.buffer[0],
+ create_tunnel_resp_pP->enb_addr.buffer[1],
+ create_tunnel_resp_pP->enb_addr.buffer[2],
+ create_tunnel_resp_pP->enb_addr.buffer[3],
+ create_tunnel_resp_pP->enb_addr.length,
+ create_tunnel_resp_pP->enb_S1u_teid[i]);
} else {
create_tunnel_resp_pP->enb_S1u_teid[i] = 0;
create_tunnel_resp_pP->status = 0xFF;
diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c
new file mode 100644
index 0000000000..f13bf13794
--- /dev/null
+++ b/openair3/GTPV1-U/gtpv1u_gNB.c
@@ -0,0 +1,311 @@
+/* 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 gtpv1u_gNB.c
+ * \brief
+ * \author Sebastien ROUX, Lionel GAUTHIER, Navid Nikaein, Panos MATZAKOS
+ * \version 1.0
+ * \company Eurecom
+ * \email: lionel.gauthier@eurecom.fr
+ */
+#include
+#include
+
+#include "mme_config.h"
+#include "intertask_interface.h"
+#include "msc.h"
+
+#include "gtpv1u.h"
+#include "NwGtpv1u.h"
+#include "NwGtpv1uMsg.h"
+#include "NwGtpv1uPrivate.h"
+#include "NwLog.h"
+#include "gtpv1u_eNB_defs.h"
+#include "gtpv1_u_messages_types.h"
+#include "udp_eNB_task.h"
+#include "common/utils/LOG/log.h"
+#include "COMMON/platform_types.h"
+#include "COMMON/platform_constants.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "common/ran_context.h"
+#include "gtpv1u_eNB_defs.h"
+#include "gtpv1u_eNB_task.h"
+#include "gtpv1u_gNB_task.h"
+#include "rrc_eNB_GTPV1U.h"
+
+#undef GTP_DUMP_SOCKET
+
+extern unsigned char NB_eNB_INST;
+
+extern RAN_CONTEXT_t RC;
+
+extern NwGtpv1uRcT gtpv1u_eNB_send_udp_msg(
+ NwGtpv1uUdpHandleT udpHandle,
+ uint8_t *buffer,
+ uint32_t buffer_len,
+ uint32_t buffer_offset,
+ uint32_t peerIpAddr,
+ uint16_t peerPort);
+
+extern NwGtpv1uRcT gtpv1u_eNB_log_request(NwGtpv1uLogMgrHandleT hLogMgr,
+ uint32_t logLevel,
+ NwCharT *file,
+ uint32_t line,
+ NwCharT *logStr);
+
+static NwGtpv1uRcT gtpv1u_start_timer_wrapper(
+ NwGtpv1uTimerMgrHandleT tmrMgrHandle,
+ uint32_t timeoutSec,
+ uint32_t timeoutUsec,
+ uint32_t tmrType,
+ void *timeoutArg,
+ NwGtpv1uTimerHandleT *hTmr) {
+ NwGtpv1uRcT rc = NW_GTPV1U_OK;
+ long timer_id;
+
+ if (tmrType == NW_GTPV1U_TMR_TYPE_ONE_SHOT) {
+ timer_setup(timeoutSec,
+ timeoutUsec,
+ TASK_GTPV1_U,
+ INSTANCE_DEFAULT,
+ TIMER_ONE_SHOT,
+ timeoutArg,
+ &timer_id);
+ } else {
+ timer_setup(timeoutSec,
+ timeoutUsec,
+ TASK_GTPV1_U,
+ INSTANCE_DEFAULT,
+ TIMER_PERIODIC,
+ timeoutArg,
+ &timer_id);
+ }
+
+ return rc;
+}
+
+
+static NwGtpv1uRcT
+gtpv1u_stop_timer_wrapper(
+ NwGtpv1uTimerMgrHandleT tmrMgrHandle,
+ NwGtpv1uTimerHandleT hTmr) {
+ NwGtpv1uRcT rc = NW_GTPV1U_OK;
+ return rc;
+}
+
+/* Callback called when a gtpv1u message arrived on UDP interface */
+NwGtpv1uRcT gtpv1u_gNB_process_stack_req(
+ NwGtpv1uUlpHandleT hUlp,
+ NwGtpv1uUlpApiT *pUlpApi) {
+ boolean_t result = FALSE;
+ teid_t teid = 0;
+ hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
+ gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
+ protocol_ctxt_t ctxt;
+ NwGtpv1uRcT rc;
+
+ switch(pUlpApi->apiType) {
+ /* Here there are two type of messages handled:
+ * - T-PDU
+ * - END-MARKER
+ */
+ case NW_GTPV1U_ULP_API_RECV_TPDU: {
+ uint8_t buffer[4096];
+ uint32_t buffer_len;
+ //uint16_t msgType = NW_GTP_GPDU;
+ //NwGtpv1uMsgT *pMsg = NULL;
+ /* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP
+ * for transmission.
+ */
+ teid = pUlpApi->apiInfo.recvMsgInfo.teid;
+ //pMsg = (NwGtpv1uMsgT *) pUlpApi->apiInfo.recvMsgInfo.hMsg;
+ //msgType = pMsg->msgType;
+
+ if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
+ buffer, &buffer_len)) {
+ LOG_E(GTPU, "Error while retrieving T-PDU");
+ }
+
+ itti_free(TASK_UDP, ((NwGtpv1uMsgT *)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf);
+#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0
+ gtpv1u_eNB_write_dump_socket(buffer,buffer_len);
+#endif
+ rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
+ pUlpApi->apiInfo.recvMsgInfo.hMsg);
+
+ if (rc != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
+ }
+
+ hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, teid, (void **)>pv1u_teid_data_p);
+
+ if (hash_rc == HASH_TABLE_OK) {
+#if defined(LOG_GTPU) && LOG_GTPU > 0
+ LOG_D(GTPU, "Received T-PDU from gtpv1u stack teid %u size %d -> enb module id %u ue module id %u rab id %u\n",
+ teid,
+ buffer_len,
+ gtpv1u_teid_data_p->enb_id,
+ gtpv1u_teid_data_p->ue_id,
+ gtpv1u_teid_data_p->eps_bearer_id);
+#endif
+ //warning "LG eps bearer mapping to DRB id to do (offset -4)"
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gtpv1u_teid_data_p->enb_id, ENB_FLAG_YES, gtpv1u_teid_data_p->ue_id, 0, 0,gtpv1u_teid_data_p->enb_id);
+ MSC_LOG_TX_MESSAGE(
+ MSC_GTPU_ENB,
+ MSC_PDCP_ENB,
+ NULL,0,
+ MSC_AS_TIME_FMT" DATA-REQ rb %u size %u",
+ 0,0,
+ (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
+ buffer_len);
+
+ result = pdcp_data_req(
+ &ctxt,
+ SRB_FLAG_NO,
+ (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
+ 0, // mui
+ SDU_CONFIRM_NO, // confirm
+ buffer_len,
+ buffer,
+ PDCP_TRANSMISSION_MODE_DATA,NULL, NULL
+ );
+
+ if ( result == FALSE ) {
+ if (ctxt.configured == FALSE )
+ LOG_W(GTPU, "gNB node PDCP data request failed, cause: [UE:%x]RB is not configured!\n", ctxt.rnti) ;
+ else
+ LOG_W(GTPU, "PDCP data request failed\n");
+
+ return NW_GTPV1U_FAILURE;
+ }
+ } else {
+ LOG_W(GTPU, "Received T-PDU from gtpv1u stack teid %u unknown size %u", teid, buffer_len);
+ }
+ }
+ break;
+
+ default: {
+ LOG_E(GTPU, "Received undefined UlpApi (%02x) from gtpv1u stack!\n",
+ pUlpApi->apiType);
+ }
+ } // end of switch
+
+ return NW_GTPV1U_OK;
+}
+
+int gtpv1u_gNB_init(void) {
+ NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
+ NwGtpv1uUlpEntityT ulp;
+ NwGtpv1uUdpEntityT udp;
+ NwGtpv1uLogMgrEntityT log;
+ NwGtpv1uTimerMgrEntityT tmr;
+ // enb_properties_p = enb_config_get()->properties[0];
+ RC.gtpv1u_data_g = (gtpv1u_data_t *)calloc(sizeof(gtpv1u_data_t),1);
+ LOG_I(GTPU, "Initializing GTPU stack %p\n",&RC.gtpv1u_data_g);
+ //gtpv1u_data_g.gtpv1u_stack;
+ /* Initialize UE hashtable */
+ RC.gtpv1u_data_g->ue_mapping = hashtable_create (32, NULL, NULL);
+ AssertFatal(RC.gtpv1u_data_g->ue_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create returned %p\n", RC.gtpv1u_data_g->ue_mapping);
+ RC.gtpv1u_data_g->teid_mapping = hashtable_create (256, NULL, NULL);
+ AssertFatal(RC.gtpv1u_data_g->teid_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create\n");
+ // RC.gtpv1u_data_g.enb_ip_address_for_S1u_S12_S4_up = enb_properties_p->enb_ipv4_address_for_S1U;
+ //gtpv1u_data_g.udp_data;
+ RC.gtpv1u_data_g->seq_num = 0;
+ RC.gtpv1u_data_g->restart_counter = 0;
+
+ /* Initializing GTPv1-U stack */
+ if ((rc = nwGtpv1uInitialize(&RC.gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc);
+ return -1;
+ }
+
+ if ((rc = nwGtpv1uSetLogLevel(RC.gtpv1u_data_g->gtpv1u_stack,
+ NW_LOG_LEVEL_DEBG)) != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "Failed to setup loglevel for stack %x\n", rc);
+ return -1;
+ }
+
+ /* Set the ULP API callback. Called once message have been processed by the
+ * nw-gtpv1u stack.
+ */
+ ulp.ulpReqCallback = gtpv1u_gNB_process_stack_req;
+ memset((void *)&(ulp.hUlp), 0, sizeof(NwGtpv1uUlpHandleT));
+
+ if ((rc = nwGtpv1uSetUlpEntity(RC.gtpv1u_data_g->gtpv1u_stack, &ulp)) != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "nwGtpv1uSetUlpEntity: %x", rc);
+ return -1;
+ }
+
+ /* nw-gtpv1u stack requires an udp callback to send data over UDP.
+ * We provide a wrapper to UDP task.
+ */
+ udp.udpDataReqCallback = gtpv1u_eNB_send_udp_msg;
+ memset((void *)&(udp.hUdp), 0, sizeof(NwGtpv1uUdpHandleT));
+
+ if ((rc = nwGtpv1uSetUdpEntity(RC.gtpv1u_data_g->gtpv1u_stack, &udp)) != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "nwGtpv1uSetUdpEntity: %x", rc);
+ return -1;
+ }
+
+ log.logReqCallback = gtpv1u_eNB_log_request;
+ memset((void *)&(log.logMgrHandle), 0, sizeof(NwGtpv1uLogMgrHandleT));
+
+ if ((rc = nwGtpv1uSetLogMgrEntity(RC.gtpv1u_data_g->gtpv1u_stack, &log)) != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "nwGtpv1uSetLogMgrEntity: %x", rc);
+ return -1;
+ }
+
+ /* Timer interface is more complicated as both wrappers doesn't send a message
+ * to the timer task but call the timer API functions start/stop timer.
+ */
+ tmr.tmrMgrHandle = 0;
+ tmr.tmrStartCallback = gtpv1u_start_timer_wrapper;
+ tmr.tmrStopCallback = gtpv1u_stop_timer_wrapper;
+
+ if ((rc = nwGtpv1uSetTimerMgrEntity(RC.gtpv1u_data_g->gtpv1u_stack, &tmr)) != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "nwGtpv1uSetTimerMgrEntity: %x", rc);
+ return -1;
+ }
+
+#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0
+
+ if ((ret = gtpv1u_eNB_create_dump_socket()) < 0) {
+ return -1;
+ }
+
+#endif
+ LOG_D(GTPU, "Initializing GTPV1U interface for eNB: DONE\n");
+ return 0;
+}
+
+void *gtpv1u_gNB_task(void *args) {
+ int rc = 0;
+ rc = gtpv1u_gNB_init();
+ AssertFatal(rc == 0, "gtpv1u_eNB_init Failed");
+ itti_mark_task_ready(TASK_GTPV1_U);
+ MSC_START_USE();
+
+ while(1) {
+ (void) gtpv1u_eNB_process_itti_msg (NULL);
+ }
+
+ return NULL;
+}
+
diff --git a/openair3/GTPV1-U/gtpv1u_gNB_task.h b/openair3/GTPV1-U/gtpv1u_gNB_task.h
new file mode 100644
index 0000000000..42fae7a714
--- /dev/null
+++ b/openair3/GTPV1-U/gtpv1u_gNB_task.h
@@ -0,0 +1,37 @@
+/* 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 gtpv1u_gNB_task.h
+* \brief
+* \author Lionel Gauthier Panos Matzakos
+* \company Eurecom
+* \email: lionel.gauthier@eurecom.fr
+*/
+
+#ifndef GTPV1U_GNB_TASK_H_
+#define GTPV1U_GNB_TASK_H_
+
+int gtpv1u_gNB_init(void);
+
+void *gtpv1u_gNB_task(void *args);
+
+
+#endif /* GTPV1U_GNB_TASK_H_ */
+
diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c
index 3592cf80a1..c228034245 100644
--- a/openair3/S1AP/s1ap_eNB.c
+++ b/openair3/S1AP/s1ap_eNB.c
@@ -69,7 +69,6 @@ s1ap_eNB_config_t s1ap_config;
static int s1ap_eNB_generate_s1_setup_request(
s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p);
-
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB);
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
@@ -361,6 +360,12 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
}
break;
+ case S1AP_E_RAB_MODIFICATION_IND: {
+ s1ap_eNB_generate_E_RAB_Modification_Indication(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+ &S1AP_E_RAB_MODIFICATION_IND(received_msg));
+ }
+ break;
+
case S1AP_UE_CONTEXT_RELEASE_COMPLETE: {
s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
@@ -508,3 +513,7 @@ static int s1ap_eNB_generate_s1_setup_request(
s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0);
return ret;
}
+
+
+
+
diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c
index 3eb182b159..4635946a05 100644
--- a/openair3/S1AP/s1ap_eNB_decoder.c
+++ b/openair3/S1AP/s1ap_eNB_decoder.c
@@ -112,6 +112,12 @@ static int s1ap_eNB_decode_successful_outcome(S1AP_S1AP_PDU_t *pdu) {
free(res.buffer);
break;
+ case S1AP_ProcedureCode_id_E_RABModificationIndication:
+ res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
+ free(res.buffer);
+ break;
+
+
default:
S1AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
(int)pdu->choice.successfulOutcome.procedureCode);
diff --git a/openair3/S1AP/s1ap_eNB_encoder.c b/openair3/S1AP/s1ap_eNB_encoder.c
index 0cd46214fc..86536ac525 100644
--- a/openair3/S1AP/s1ap_eNB_encoder.c
+++ b/openair3/S1AP/s1ap_eNB_encoder.c
@@ -118,15 +118,20 @@ int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu,
free(res.buffer);
break;
+ case S1AP_ProcedureCode_id_E_RABModificationIndication:
+ res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu);
+ free(res.buffer);
+ break;
+
default:
S1AP_DEBUG("Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
return -1;
}
- if (asn1_xer_print) {
+ //if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_S1AP_S1AP_PDU, (void *)pdu);
- }
+ //}
memset(&res, 0, sizeof(res));
res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu);
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index 87abc1ede9..28ee11187e 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -104,6 +104,11 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_
uint32_t stream,
S1AP_S1AP_PDU_t *pdu);
+static
+int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id,
+ uint32_t stream,
+ S1AP_S1AP_PDU_t *pdu);
+
/* Handlers matrix. Only eNB related procedure present here */
s1ap_message_decoded_callback messages_callback[][3] = {
{ 0, 0, 0 }, /* HandoverPreparation */
@@ -154,6 +159,9 @@ s1ap_message_decoded_callback messages_callback[][3] = {
{ 0, 0, 0 }, /* UplinkUEAssociatedLPPaTransport */
{ 0, 0, 0 }, /* DownlinkNonUEAssociatedLPPaTransport */
{ 0, 0, 0 }, /* UplinkNonUEAssociatedLPPaTransport */
+ { 0, 0, 0 }, /* UERadioCapabilityMatch */
+ { 0, 0, 0 }, /* PWSRestartIndication */
+ { 0, s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm, 0 }, /* E_RABModificationIndication */
};
char *s1ap_direction2String(int s1ap_dir) {
static char *s1ap_direction_String[] = {
@@ -1722,3 +1730,13 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_
// TODO continue
return 0;
}
+
+static
+int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id,
+ uint32_t stream,
+ S1AP_S1AP_PDU_t *pdu){
+
+ LOG_W(S1AP, "Implementation of S1AP E-RAB Modification confirm handler is pending...\n");
+ return 0;
+}
+
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index d271ddf6ba..c668e32d1b 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -1620,3 +1620,319 @@ int s1ap_eNB_path_switch_req(instance_t instance,
return ret;
}
+
+
+//-----------------------------------------------------------------------------
+/*
+* eNB generate a S1 E_RAB Modification Indication towards MME
+*/
+/*int s1ap_eNB_generate_E_RAB_Modification_Indication(
+ instance_t instance,
+ s1ap_e_rab_modification_ind_t *e_rab_modification_ind)
+//-----------------------------------------------------------------------------
+{
+ struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
+ S1AP_S1AP_PDU_t pdu;
+ S1AP_E_RABModificationIndication_t *out = NULL;
+ S1AP_E_RABModificationIndicationIEs_t *ie = NULL;
+ S1AP_E_RABToBeModifiedItemBearerModInd_t *E_RAB_ToBeModifiedItem_BearerModInd = NULL;
+ S1AP_E_RABToBeModifiedItemBearerModIndIEs_t *E_RAB_ToBeModifiedItem_BearerModInd_IEs = NULL;
+
+ S1AP_E_RABNotToBeModifiedItemBearerModInd_t *E_RAB_NotToBeModifiedItem_BearerModInd = NULL;
+ S1AP_E_RABNotToBeModifiedItemBearerModIndIEs_t *E_RAB_NotToBeModifiedItem_BearerModInd_IEs = NULL;
+
+
+ s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
+ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
+ uint8_t *buffer = NULL;
+ uint32_t len = 0;
+ int ret = 0;
+ DevAssert(s1ap_eNB_instance_p != NULL);
+ DevAssert(e_rab_modification_ind != NULL);
+
+ int num_e_rabs_tobemodified = e_rab_modification_ind->nb_of_e_rabs_tobemodified;
+ int num_e_rabs_nottobemodified = e_rab_modification_ind->nb_of_e_rabs_nottobemodified;
+
+ uint32_t CSG_id = 0;
+
+ if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
+ e_rab_modification_ind->eNB_ue_s1ap_id)) == NULL) {
+ // The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs
+ S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n",
+ e_rab_modification_ind->eNB_ue_s1ap_id);
+ return -1;
+ }
+
+ // Prepare the S1AP message to encode
+ memset(&pdu, 0, sizeof(pdu));
+ pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
+ pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_E_RABModificationIndication;
+ pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject;
+ pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_E_RABModificationIndication;
+ out = &pdu.choice.initiatingMessage.value.choice.E_RABModificationIndication;
+ // mandatory
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_MME_UE_S1AP_ID;
+ ie->value.choice.MME_UE_S1AP_ID = e_rab_modification_ind->mme_ue_s1ap_id;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_ENB_UE_S1AP_ID;
+ ie->value.choice.ENB_UE_S1AP_ID = e_rab_modification_ind->eNB_ue_s1ap_id;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ //E-RABs to be modified list
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModInd;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABToBeModifiedListBearerModInd;
+
+ //The following two for-loops here will probably need to change. We should do a different type of search
+ for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedItemBearerModInd;
+ E_RAB_ToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject;
+ E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABToBeModifiedItemBearerModIndIEs__value_PR_E_RABToBeModifiedItemBearerModInd;
+ E_RAB_ToBeModifiedItem_BearerModInd = &E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABToBeModifiedItemBearerModInd;
+
+ {
+ E_RAB_ToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_tobemodified[i].e_rab_id;
+
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length/8;
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length%8;
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf = calloc(1, E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+ memcpy (E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.buffer,
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+
+ INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_tobemodified[i].gtp_teid, &E_RAB_ToBeModifiedItem_BearerModInd->dL_GTP_TEID);
+
+ }
+ ASN_SEQUENCE_ADD(&ie->value.choice.E_RABToBeModifiedListBearerModInd.list, E_RAB_ToBeModifiedItem_BearerModInd_IEs);
+ }
+
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ //E-RABs NOT to be modified list
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedListBearerModInd;
+ ie->criticality = S1AP_Criticality_reject;
+ if(num_e_rabs_nottobemodified > 0) {
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd;
+
+ for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedItemBearerModInd;
+ E_RAB_NotToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject;
+ E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABNotToBeModifiedItemBearerModIndIEs__value_PR_E_RABNotToBeModifiedItemBearerModInd;
+ E_RAB_NotToBeModifiedItem_BearerModInd = &E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABNotToBeModifiedItemBearerModInd;
+
+ {
+ E_RAB_NotToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_nottobemodified[i].e_rab_id;
+
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.length/8;
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.length%8;
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf =
+ calloc(1, E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+ memcpy (E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.buffer,
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+
+ INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_nottobemodified[i].gtp_teid, &E_RAB_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID);
+
+ }
+ ASN_SEQUENCE_ADD(&ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list, E_RAB_NotToBeModifiedItem_BearerModInd_IEs);
+ }
+ }
+ else{
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd;
+ ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list.size = 0;
+ }
+
+
+
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_CSGMembershipInfo;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_CSGMembershipInfo;
+ ie->value.choice.CSGMembershipInfo.cSGMembershipStatus = S1AP_CSGMembershipStatus_member;
+ INT32_TO_BIT_STRING(CSG_id, &ie->value.choice.CSGMembershipInfo.cSG_Id);
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+
+ if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+ S1AP_ERROR("Failed to encode S1 E-RAB modification indication \n");
+ return -1;
+ }
+
+ // Non UE-Associated signalling -> stream = 0
+ S1AP_INFO("Size of encoded message: %d \n", len);
+ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
+ ue_context_p->mme_ref->assoc_id, buffer,
+ len, ue_context_p->tx_stream);
+
+//s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, len, 0);
+ return ret;
+}*/
+
+int s1ap_eNB_generate_E_RAB_Modification_Indication(
+ instance_t instance,
+ s1ap_e_rab_modification_ind_t *e_rab_modification_ind)
+//-----------------------------------------------------------------------------
+{
+ struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
+ S1AP_S1AP_PDU_t pdu;
+ S1AP_E_RABModificationIndication_t *out = NULL;
+ S1AP_E_RABModificationIndicationIEs_t *ie = NULL;
+ S1AP_E_RABToBeModifiedItemBearerModInd_t *E_RAB_ToBeModifiedItem_BearerModInd = NULL;
+ S1AP_E_RABToBeModifiedItemBearerModIndIEs_t *E_RAB_ToBeModifiedItem_BearerModInd_IEs = NULL;
+
+ //S1AP_E_RABNotToBeModifiedItemBearerModInd_t *E_RAB_NotToBeModifiedItem_BearerModInd = NULL;
+ //S1AP_E_RABNotToBeModifiedItemBearerModIndIEs_t *E_RAB_NotToBeModifiedItem_BearerModInd_IEs = NULL;
+
+
+ s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
+ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
+ uint8_t *buffer = NULL;
+ uint32_t len = 0;
+ int ret = 0;
+ DevAssert(s1ap_eNB_instance_p != NULL);
+ DevAssert(e_rab_modification_ind != NULL);
+
+ int num_e_rabs_tobemodified = e_rab_modification_ind->nb_of_e_rabs_tobemodified;
+ //int num_e_rabs_nottobemodified = e_rab_modification_ind->nb_of_e_rabs_nottobemodified;
+
+ //uint32_t CSG_id = 0;
+ //uint32_t pseudo_gtp_teid = 10;
+
+ if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
+ e_rab_modification_ind->eNB_ue_s1ap_id)) == NULL) {
+ // The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs
+ S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n",
+ e_rab_modification_ind->eNB_ue_s1ap_id);
+ return -1;
+ }
+
+ // Prepare the S1AP message to encode
+ memset(&pdu, 0, sizeof(pdu));
+ pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
+ pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_E_RABModificationIndication;
+ pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject;
+ pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_E_RABModificationIndication;
+ out = &pdu.choice.initiatingMessage.value.choice.E_RABModificationIndication;
+ /* mandatory */
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_MME_UE_S1AP_ID;
+ ie->value.choice.MME_UE_S1AP_ID = e_rab_modification_ind->mme_ue_s1ap_id;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_ENB_UE_S1AP_ID;
+ ie->value.choice.ENB_UE_S1AP_ID = e_rab_modification_ind->eNB_ue_s1ap_id;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ //E-RABs to be modified list
+ ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModInd;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABToBeModifiedListBearerModInd;
+
+ //The following two for-loops here will probably need to change. We should do a different type of search
+ for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedItemBearerModInd;
+ E_RAB_ToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject;
+ E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABToBeModifiedItemBearerModIndIEs__value_PR_E_RABToBeModifiedItemBearerModInd;
+ E_RAB_ToBeModifiedItem_BearerModInd = &E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABToBeModifiedItemBearerModInd;
+
+ {
+ E_RAB_ToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_tobemodified[i].e_rab_id;
+
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length/8;
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length%8;
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf = calloc(1, E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+ memcpy (E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.buffer,
+ E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+
+ INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_tobemodified[i].gtp_teid, &E_RAB_ToBeModifiedItem_BearerModInd->dL_GTP_TEID);
+
+ }
+ ASN_SEQUENCE_ADD(&ie->value.choice.E_RABToBeModifiedListBearerModInd.list, E_RAB_ToBeModifiedItem_BearerModInd_IEs);
+ }
+
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ //E-RABs NOT to be modified list
+ /*ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedListBearerModInd;
+ ie->criticality = S1AP_Criticality_reject;
+ //if(num_e_rabs_nottobemodified > 0) {
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd;
+
+ for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedItemBearerModInd;
+ E_RAB_NotToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject;
+ E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABNotToBeModifiedItemBearerModIndIEs__value_PR_E_RABNotToBeModifiedItemBearerModInd;
+ E_RAB_NotToBeModifiedItem_BearerModInd = &E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABNotToBeModifiedItemBearerModInd;
+
+ {
+ E_RAB_NotToBeModifiedItem_BearerModInd->e_RAB_ID = 10; //e_rab_modification_ind->e_rabs_tobemodified[i].e_rab_id;
+
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length/8;
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length%8;
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf =
+ calloc(1, E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+ memcpy (E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.buffer,
+ E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size);
+
+ //INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_tobemodified[i].gtp_teid, &E_RAB_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID);
+ INT32_TO_OCTET_STRING(pseudo_gtp_teid, &E_RAB_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID);
+
+ }
+ ASN_SEQUENCE_ADD(&ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list, E_RAB_NotToBeModifiedItem_BearerModInd_IEs);
+ }
+ // }
+ //else{
+// ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd;
+// ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list.size = 0;
+// } /
+
+
+
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);*/
+
+ /*ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_CSGMembershipInfo;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_CSGMembershipInfo;
+ ie->value.choice.CSGMembershipInfo.cSGMembershipStatus = S1AP_CSGMembershipStatus_member;
+ INT32_TO_BIT_STRING(CSG_id, &ie->value.choice.CSGMembershipInfo.cSG_Id);
+ ie->value.choice.CSGMembershipInfo.cSG_Id.bits_unused=5;
+ ie->value.choice.CSGMembershipInfo.cellAccessMode = S1AP_CellAccessMode_hybrid;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);*/
+
+ if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+ S1AP_ERROR("Failed to encode S1 E-RAB modification indication \n");
+ return -1;
+ }
+
+ // Non UE-Associated signalling -> stream = 0
+ S1AP_INFO("Size of encoded message: %d \n", len);
+ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
+ ue_context_p->mme_ref->assoc_id, buffer,
+ len, ue_context_p->tx_stream);
+
+//s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, len, 0);
+ return ret;
+}
+
+
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.h b/openair3/S1AP/s1ap_eNB_nas_procedures.h
index c425719872..47f71cc795 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.h
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.h
@@ -52,4 +52,8 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance,
int s1ap_eNB_path_switch_req(instance_t instance,
s1ap_path_switch_req_t *path_switch_req_p);
+
+int s1ap_eNB_generate_E_RAB_Modification_Indication(
+ instance_t instance, s1ap_e_rab_modification_ind_t *e_rab_modification_ind);
+
#endif /* S1AP_ENB_NAS_PROCEDURES_H_ */
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 45412f9eea..ad880e3cbf 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -476,14 +476,16 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
b->trashingPacket=true;
} else if ( b->lastReceivedTS < b->th.timestamp) {
int nbAnt= b->th.nbAnt;
-
+ if ( b->th.timestamp-b->lastReceivedTS < CirSize ) {
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) {
for (int a=0; a < nbAnt; a++) {
b->circularBuf[(index*nbAnt+a)%CirSize].r = 0;
b->circularBuf[(index*nbAnt+a)%CirSize].i = 0;
}
}
-
+ } else {
+ memset(b->circularBuf, 0, sampleToByte(CirSize,1));
+ }
if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS > 50 )
LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS );
b->lastReceivedTS=b->th.timestamp;
@@ -646,10 +648,11 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
);
else { // no channel modeling
sample_t *out=(sample_t *)samplesVoid[a];
-
+ const int64_t base=t->nextTimestamp*nbAnt+a;
for ( int i=0; i < nsamps; i++ ) {
- out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize].r;
- out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize].i;
+ const int idx=(i*nbAnt+base)%CirSize;
+ out[i].r+=ptr->circularBuf[idx].r;
+ out[i].i+=ptr->circularBuf[idx].i;
}
} // end of no channel modeling
} // end for a...
diff --git a/targets/COMMON/create_nr_tasks.c b/targets/COMMON/create_nr_tasks.c
index 24c4115980..13f72b3876 100644
--- a/targets/COMMON/create_nr_tasks.c
+++ b/targets/COMMON/create_nr_tasks.c
@@ -51,17 +51,17 @@ int create_gNB_tasks(uint32_t gnb_nb)
}
if (gnb_nb > 0) {
- /* Last task to create, others task must be ready before its start */
+ // Last task to create, others task must be ready before its start
if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1;
}
}
-/*
+
if (EPC_MODE_ENABLED) {
if (gnb_nb > 0) {
- if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
+ /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
}
@@ -69,7 +69,7 @@ int create_gNB_tasks(uint32_t gnb_nb)
if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
LOG_E(S1AP, "Create task for S1AP failed\n");
return -1;
- }
+ }*/
if(!emulate_rf){
if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
LOG_E(UDP_, "Create task for UDP failed\n");
@@ -84,7 +84,15 @@ int create_gNB_tasks(uint32_t gnb_nb)
}
}
-*/
+
+ /*if (gnb_nb > 0) {
+ // Last task to create, others task must be ready before its start
+ if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
+ LOG_E(GNB_APP, "Create task for gNB APP failed\n");
+ return -1;
+ }
+ }*/
+
if (gnb_nb > 0) {
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
@@ -100,4 +108,4 @@ int create_gNB_tasks(uint32_t gnb_nb)
return 0;
}
-#endif
+//#endif
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
index 1363be3bce..d5bc492644 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
@@ -105,8 +105,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,8 +114,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
index 1fbc8e30ef..93a6c7fbc9 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
@@ -105,8 +105,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,8 +114,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
new file mode 100644
index 0000000000..81796ada2c
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
@@ -0,0 +1,295 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+ ////////// Identification parameters:
+ gNB_ID = 0xe00;
+
+ cell_type = "CELL_MACRO_GNB";
+
+ gNB_name = "gNB-Eurecom-5GNRBox";
+
+ // Tracking area code, 0x0000 and 0xfffe are reserved values
+ tracking_area_code = 1;
+
+ plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+ tr_s_preference = "local_mac"
+
+ ////////// Physical parameters:
+
+ ssb_SubcarrierOffset = 0;
+ pdsch_AntennaPorts = 1;
+
+ servingCellConfigCommon = (
+ {
+ #spCellConfigCommon
+
+ physCellId = 0;
+
+# downlinkConfigCommon
+ #frequencyInfoDL
+ # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+ absoluteFrequencySSB = 641032;
+ dl_frequencyBand = 78;
+ # this is 3600 MHz
+ dl_absoluteFrequencyPointA = 640000;
+ #scs-SpecificCarrierList
+ dl_offstToCarrier = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ dl_subcarrierSpacing = 1;
+ dl_carrierBandwidth = 106;
+ #initialDownlinkBWP
+ #genericParameters
+ # this is RBstart=0,L=50 (275*(L-1))+RBstart
+ initialDLBWPlocationAndBandwidth = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ initialDLBWPsubcarrierSpacing = 1;
+ #pdcch-ConfigCommon
+ initialDLBWPcontrolResourceSetZero = 12;
+ initialDLBWPsearchSpaceZero = 0;
+ #pdsch-ConfigCommon
+ #pdschTimeDomainAllocationList (up to 16 entries)
+ initialDLBWPk0_0 = 0;
+ #initialULBWPmappingType
+ #0=typeA,1=typeB
+ initialDLBWPmappingType_0 = 0;
+ #this is SS=1,L=13
+ initialDLBWPstartSymbolAndLength_0 = 40;
+
+ initialDLBWPk0_1 = 0;
+ initialDLBWPmappingType_1 = 0;
+ #this is SS=2,L=12
+ initialDLBWPstartSymbolAndLength_1 = 53;
+
+ initialDLBWPk0_2 = 0;
+ initialDLBWPmappingType_2 = 0;
+ #this is SS=1,L=12
+ initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=4
+ initialDLBWPstartSymbolAndLength_3 = 57;
+
+ #uplinkConfigCommon
+ #frequencyInfoUL
+ ul_frequencyBand = 78;
+ #scs-SpecificCarrierList
+ ul_offstToCarrier = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ ul_subcarrierSpacing = 1;
+ ul_carrierBandwidth = 106;
+ pMax = 20;
+ #initialUplinkBWP
+ #genericParameters
+ initialULBWPlocationAndBandwidth = 6366;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ initialULBWPsubcarrierSpacing = 1;
+ #rach-ConfigCommon
+ #rach-ConfigGeneric
+ prach_ConfigurationIndex = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+ prach_msg1_FDM = 0;
+ prach_msg1_FrequencyStart = 0;
+ zeroCorrelationZoneConfig = 13;
+ preambleReceivedTargetPower = -118;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+ preambleTransMax = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+ powerRampingStep = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+ ra_ResponseWindow = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
+#oneHalf (0..15) 4,8,12,16,...60,64
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
+#ra_ContentionResolutionTimer
+#(0..7) 8,16,24,32,40,48,56,64
+ ra_ContentionResolutionTimer = 7;
+ rsrp_ThresholdSSB = 19;
+#prach-RootSequenceIndex_PR
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
+ prach_RootSequenceIndex = 1;
+ # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
+ #
+ msg1_SubcarrierSpacing = 1,
+
+# restrictedSetConfig
+# 0=unrestricted, 1=restricted type A, 2=restricted type B
+ restrictedSetConfig = 0,
+ # pusch-ConfigCommon (up to 16 elements)
+ initialULBWPk2_0 = 2;
+ initialULBWPmappingType_0 = 1
+ # this is SS=0 L=11
+ initialULBWPstartSymbolAndLength_0 = 55;
+
+ initialULBWPk2_1 = 2;
+ initialULBWPmappingType_1 = 1;
+ # this is SS=0 L=12
+ initialULBWPstartSymbolAndLength_1 = 69;
+
+ initialULBWPk2_2 = 7;
+ initialULBWPmappingType_2 = 1;
+ # this is SS=10 L=4
+ initialULBWPstartSymbolAndLength_2 = 52;
+
+
+ msg3_DeltaPreamble = 1;
+ p0_NominalWithGrant =-90;
+
+# pucch-ConfigCommon setup :
+# pucchGroupHopping
+# 0 = neither, 1= group hopping, 2=sequence hopping
+ pucchGroupHopping = 0;
+ hoppingId = 40;
+ p0_nominal = -90;
+# ssb_PositionsInBurs_BitmapPR
+# 1=short, 2=medium, 3=long
+ ssb_PositionsInBurst_PR = 2;
+ ssb_PositionsInBurst_Bitmap = 1;
+
+# ssb_periodicityServingCell
+# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
+ ssb_periodicityServingCell = 2;
+
+# dmrs_TypeA_position
+# 0 = pos2, 1 = pos3
+ dmrs_TypeA_Position = 0;
+
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ subcarrierSpacing = 1;
+
+
+ #tdd-UL-DL-ConfigurationCommon
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ referenceSubcarrierSpacing = 1;
+ # pattern1
+ # dl_UL_TransmissionPeriodicity
+ # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
+ dl_UL_TransmissionPeriodicity = 6;
+ nrofDownlinkSlots = 7;
+ nrofDownlinkSymbols = 6;
+ nrofUplinkSlots = 2;
+ nrofUplinkSymbols = 4;
+
+ ssPBCH_BlockPower = 10;
+ }
+
+ );
+
+
+ # ------- SCTP definitions
+ SCTP :
+ {
+ # Number of streams to use in input/output
+ SCTP_INSTREAMS = 2;
+ SCTP_OUTSTREAMS = 2;
+ };
+
+
+ ////////// MME parameters:
+ mme_ip_address = ( { ipv4 = "192.168.12.26";
+ ipv6 = "192:168:30::17";
+ active = "yes";
+ preference = "ipv4";
+ }
+ );
+
+ ///X2
+ enable_x2 = "yes";
+ t_reloc_prep = 1000; /* unit: millisecond */
+ tx2_reloc_overall = 2000; /* unit: millisecond */
+ target_enb_x2_ip_address = (
+ { ipv4 = "192.168.12.188";
+ ipv6 = "192:168:30::17";
+ preference = "ipv4";
+ }
+ );
+
+ NETWORK_INTERFACES :
+ {
+
+ GNB_INTERFACE_NAME_FOR_S1_MME = "enp0s31f6";
+ GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.75/24";
+ GNB_INTERFACE_NAME_FOR_S1U = "eth0";
+ GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.75/24";
+ GNB_PORT_FOR_S1U = 2152; # Spec 2152
+
+ GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.75/23";
+ GNB_PORT_FOR_X2C = 36422; # Spec 36422
+ };
+ }
+);
+
+MACRLCs = (
+ {
+ num_cc = 1;
+ tr_s_preference = "local_L1";
+ tr_n_preference = "local_RRC";
+ }
+);
+
+L1s = (
+ {
+ num_cc = 1;
+ tr_n_preference = "local_mac";
+ }
+);
+
+RUs = (
+ {
+ local_rf = "yes"
+ nb_tx = 1
+ nb_rx = 1
+ att_tx = 0
+ att_rx = 0;
+ bands = [7];
+ max_pdschReferenceSignalPower = -27;
+ max_rxgain = 114;
+ eNB_instances = [0];
+ sdr_addrs = "addr=192.168.20.2,mgmt_addr=192.168.20.2";
+ clock_src = "internal";
+ }
+);
+
+THREAD_STRUCT = (
+ {
+ #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+ parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
+ #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+ worker_config = "WORKER_ENABLE";
+ }
+);
+
+ log_config :
+ {
+ global_log_level ="info";
+ global_log_verbosity ="medium";
+ hw_log_level ="info";
+ hw_log_verbosity ="medium";
+ phy_log_level ="info";
+ phy_log_verbosity ="medium";
+ mac_log_level ="info";
+ mac_log_verbosity ="high";
+ rlc_log_level ="info";
+ rlc_log_verbosity ="medium";
+ pdcp_log_level ="info";
+ pdcp_log_verbosity ="medium";
+ rrc_log_level ="info";
+ rrc_log_verbosity ="medium";
+ };
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
index fed15739cf..2c37e0d03f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -46,7 +46,7 @@ gNBs =
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=50 (275*(L-1))+RBstart
- initialDLBWPlocationAndBandwidth = 13475;
+ initialDLBWPlocationAndBandwidth = 6366;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
@@ -59,7 +59,7 @@ gNBs =
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
- #this is SS=2,L=3
+ #this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
@@ -71,6 +71,12 @@ gNBs =
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=4
+ initialDLBWPstartSymbolAndLength_3 = 57;
+
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -83,7 +89,7 @@ gNBs =
pMax = 20;
#initialUplinkBWP
#genericParameters
- initialULBWPlocationAndBandwidth = 13475;
+ initialULBWPlocationAndBandwidth = 6366;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
@@ -105,8 +111,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,16 +120,16 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
-
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
+
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2;
initialULBWPmappingType_0 = 1
@@ -135,6 +141,11 @@ gNBs =
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPk2_2 = 7;
+ initialULBWPmappingType_2 = 1;
+ # this is SS=10 L=4
+ initialULBWPstartSymbolAndLength_2 = 52;
+
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
index 2e643d8392..0b04dc82d1 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
@@ -59,7 +59,7 @@ gNBs =
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
- #this is SS=2,L=3
+ #this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
@@ -71,6 +71,11 @@ gNBs =
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=5
+ initialDLBWPstartSymbolAndLength_3 = 57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -105,8 +110,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,8 +119,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
index b82c455ef4..ae17efc9bd 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
@@ -59,7 +59,7 @@ gNBs =
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
- #this is SS=2,L=3
+ #this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
@@ -71,6 +71,11 @@ gNBs =
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=5
+ initialDLBWPstartSymbolAndLength_3 = 57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -105,8 +110,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,8 +119,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
index 4cbec5b86e..c907dcfe8d 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
@@ -59,7 +59,7 @@ gNBs =
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
- #this is SS=2,L=3
+ #this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
@@ -71,6 +71,11 @@ gNBs =
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=5
+ initialDLBWPstartSymbolAndLength_3 = 57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -105,8 +110,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,8 +119,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
index 08bfeea7ee..464ce6b9aa 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
@@ -59,7 +59,7 @@ gNBs =
#initialULBWPmappingType
#0=typeA,1=typeB
initialDLBWPmappingType_0 = 0;
- #this is SS=2,L=3
+ #this is SS=1,L=13
initialDLBWPstartSymbolAndLength_0 = 40;
initialDLBWPk0_1 = 0;
@@ -71,6 +71,11 @@ gNBs =
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=5
+ initialDLBWPstartSymbolAndLength_3 = 57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -105,8 +110,8 @@ gNBs =
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
-#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen
- ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
+#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
+ ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
@@ -114,8 +119,8 @@ gNBs =
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
-#0 = 839, 1 = 139
- prach_RootSequenceIndex_PR = 1;
+#1 = 839, 2 = 139
+ prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#