merge develop, use Linux crypto library
This commit is contained in:
@@ -131,12 +131,12 @@ gNBs =
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
# pusch-ConfigCommon (up to 16 elements)
|
||||
initialULBWPk2_0 = 2;
|
||||
initialULBWPk2_0 = 6;
|
||||
initialULBWPmappingType_0 = 1
|
||||
# this is SS=0 L=11
|
||||
initialULBWPstartSymbolAndLength_0 = 55;
|
||||
|
||||
initialULBWPk2_1 = 2;
|
||||
initialULBWPk2_1 = 6;
|
||||
initialULBWPmappingType_1 = 1;
|
||||
# this is SS=0 L=12
|
||||
initialULBWPstartSymbolAndLength_1 = 69;
|
||||
|
||||
@@ -765,6 +765,59 @@ function report_test {
|
||||
echo " <td align = \"center\" colspan = 4 >Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB </td>" >> ./test_simulator_results.html
|
||||
fi
|
||||
echo " </tr>" >> ./test_simulator_results.html
|
||||
|
||||
#RA test (--do-ra option)
|
||||
|
||||
#build log files names
|
||||
RA_ENB_LOG=$ARCHIVES_LOC/ra_check_${TMODE}_${BW}prb_${CN_CONFIG}_gnb.log
|
||||
RA_UE_LOG=$ARCHIVES_LOC/ra_check_${TMODE}_${BW}prb_${CN_CONFIG}_ue.log
|
||||
if [ -f $RA_ENB_LOG ] && [ -f $RA_UE_LOG ]
|
||||
then
|
||||
#get rid of full path
|
||||
NAME_ENB=`echo $RA_ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"`
|
||||
NAME_UE=`echo $RA_UE_LOG | sed -e "s#$ARCHIVES_LOC/##"`
|
||||
echo " <tr>" >> ./test_simulator_results.html
|
||||
echo " <td>$NAME_ENB --- $NAME_UE</td>" >> ./test_simulator_results.html
|
||||
echo " <td>Check if RA proc succeeded</td>" >> ./test_simulator_results.html
|
||||
|
||||
#gNB RA check
|
||||
GNB_RECEIVED=`egrep -c "received correctly" $RA_ENB_LOG`
|
||||
GNB_CONNECTED=`egrep -c "now 5G connected" $RA_ENB_LOG`
|
||||
#UE RA check
|
||||
UE_RA_PROC_OK=`egrep -c "RA procedure succeeded" $RA_UE_LOG`
|
||||
|
||||
|
||||
if [ $GNB_RECEIVED -gt 0 ] && [ $GNB_CONNECTED -gt 0 ] && [ $UE_RA_PROC_OK -gt 0 ]
|
||||
then
|
||||
echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html
|
||||
else
|
||||
echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
|
||||
fi
|
||||
|
||||
echo " <td><pre>" >> ./test_simulator_results.html
|
||||
if [ $GNB_RECEIVED -gt 0 ]
|
||||
then
|
||||
echo "<font color = \"blue\">- gNB --> RA received</font>" >> ./test_simulator_results.html
|
||||
else
|
||||
echo "<font color = \"red\"><b>- gNB RA NOT RECEIVED</b></font>" >> ./test_simulator_results.html
|
||||
fi
|
||||
if [ $GNB_CONNECTED -gt 0 ]
|
||||
then
|
||||
echo "<font color = \"blue\">- gNB --> 5G connected</font>" >> ./test_simulator_results.html
|
||||
else
|
||||
echo "<font color = \"red\"><b>- gNB NOT 5G CONNECTED</b></font>" >> ./test_simulator_results.html
|
||||
fi
|
||||
if [ $UE_RA_PROC_OK -gt 0 ]
|
||||
then
|
||||
echo "<font color = \"blue\">- NR UE --> RA procedure succeded</font>" >> ./test_simulator_results.html
|
||||
else
|
||||
echo "<font color = \"red\"><b>- NR UE RA procedure failed</b></font>" >> ./test_simulator_results.html
|
||||
fi
|
||||
echo " </pre></td>" >> ./test_simulator_results.html
|
||||
echo " </tr>" >> ./test_simulator_results.html
|
||||
fi
|
||||
|
||||
#SYNC test
|
||||
ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb.log
|
||||
UE_LOG=`echo $ENB_LOG | sed -e "s#gnb#ue#"`
|
||||
if [ -f $ENB_LOG ] && [ -f $UE_LOG ]
|
||||
|
||||
@@ -276,6 +276,22 @@ function check_ping_result {
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function check_ra_result {
|
||||
local LOC_GNB_LOG=$1
|
||||
local LOC_UE_LOG=$2
|
||||
|
||||
#gNB RA test
|
||||
echo "Checking gNB Log for RA success"
|
||||
egrep "received correctly" $1
|
||||
egrep "now 5G connected" $1
|
||||
|
||||
#UE RA test
|
||||
echo 'Checking UE Log for RA success'
|
||||
egrep "RA procedure succeeded" $2
|
||||
|
||||
}
|
||||
|
||||
# In DL: iperf server should be on UE side
|
||||
# -B oaitun_ue{j}-IP-Addr
|
||||
# iperf client should be on EPC (S1) or eNB (noS1) side
|
||||
@@ -1172,6 +1188,8 @@ 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
|
||||
#LOC_RA_TEST=1 will run the RA test check
|
||||
local LOC_RA_TEST=$7
|
||||
|
||||
if [ -e rbconfig.raw ]; then rm -f rbconfig.raw; fi
|
||||
if [ -e reconfig.raw ]; then rm -f reconfig.raw; fi
|
||||
@@ -1192,7 +1210,12 @@ function start_rf_sim_gnb {
|
||||
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
|
||||
if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option
|
||||
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
|
||||
else #RA test => use --do-ra option
|
||||
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 --do-ra\" > ./my-nr-softmodem-run.sh " >> $1
|
||||
fi
|
||||
fi
|
||||
echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
|
||||
echo "cat ./my-nr-softmodem-run.sh" >> $1
|
||||
@@ -1249,6 +1272,8 @@ function start_rf_sim_gnb {
|
||||
echo "RF-SIM gNB oaitun_enb1 is UP and CONFIGURED"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
sleep 10
|
||||
echo "echo \"free -m\"" > $1
|
||||
echo "free -m" >> $1
|
||||
@@ -1267,6 +1292,8 @@ 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
|
||||
#LOC_RA_TEST=1 will run the RA test check
|
||||
local LOC_RA_TEST=$8
|
||||
|
||||
# Copy the RAW files from the gNB run
|
||||
scp -o StrictHostKeyChecking=no rbconfig.raw ubuntu@$LOC_NR_UE_VM_IP_ADDR:/home/ubuntu/tmp
|
||||
@@ -1281,7 +1308,12 @@ function start_rf_sim_nr_ue {
|
||||
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/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1
|
||||
if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option
|
||||
then
|
||||
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
|
||||
else #RA test => use --do-ra option
|
||||
echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --do-ra --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
|
||||
fi
|
||||
echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1
|
||||
echo "cat ./my-nr-softmodem-run.sh" >> $1
|
||||
@@ -1340,6 +1372,8 @@ function start_rf_sim_nr_ue {
|
||||
echo "RF-SIM NR-UE oaitun_ue1 is UP and CONFIGURED"
|
||||
fi
|
||||
sleep 10
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2138,6 +2172,8 @@ function run_test_on_vm {
|
||||
######### start of loop
|
||||
while [ $try_cnt -lt 4 ]
|
||||
do
|
||||
|
||||
#start RA test
|
||||
SYNC_STATUS=0
|
||||
PING_STATUS=0
|
||||
IPERF_STATUS=0
|
||||
@@ -2146,13 +2182,69 @@ function run_test_on_vm {
|
||||
echo "${CN_CONFIG} : Starting the gNB"
|
||||
echo "############################################################"
|
||||
CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log
|
||||
start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG
|
||||
#last argument = 1 is to enable --do-ra for RA test
|
||||
start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 1
|
||||
|
||||
echo "############################################################"
|
||||
echo "${CN_CONFIG} : Starting the NR-UE"
|
||||
echo "############################################################"
|
||||
CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log
|
||||
start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG
|
||||
#last argument = 1 is to enable --do-ra for RA test
|
||||
start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1
|
||||
if [ $NR_UE_SYNC -eq 0 ]
|
||||
then
|
||||
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
|
||||
fi
|
||||
|
||||
|
||||
echo "############################################################"
|
||||
echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators"
|
||||
echo "############################################################"
|
||||
sleep 20
|
||||
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
|
||||
|
||||
|
||||
|
||||
#check RA markers in gNB and NR UE log files
|
||||
echo "############################################################"
|
||||
echo "${CN_CONFIG} : Checking RA on gNB / NR-UE"
|
||||
echo "############################################################"
|
||||
|
||||
mv $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_GNB_LOG_FILE
|
||||
mv $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_NR_UE_LOG_FILE
|
||||
check_ra_result $ARCHIVES_LOC/ra_check_$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_NR_UE_LOG_FILE
|
||||
|
||||
|
||||
#end RA test
|
||||
|
||||
|
||||
|
||||
|
||||
SYNC_STATUS=0
|
||||
PING_STATUS=0
|
||||
IPERF_STATUS=0
|
||||
|
||||
echo "############################################################"
|
||||
echo "${CN_CONFIG} : Starting the gNB"
|
||||
echo "############################################################"
|
||||
CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log
|
||||
start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 0
|
||||
|
||||
echo "############################################################"
|
||||
echo "${CN_CONFIG} : Starting the NR-UE"
|
||||
echo "############################################################"
|
||||
CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log
|
||||
start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 0
|
||||
if [ $NR_UE_SYNC -eq 0 ]
|
||||
then
|
||||
echo "Problem w/ gNB and NR-UE not syncing"
|
||||
|
||||
@@ -2114,7 +2114,7 @@ add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag)
|
||||
|
||||
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)
|
||||
add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c)
|
||||
|
||||
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
|
||||
include_directories("${OPENAIR2_DIR}/LAYER2")
|
||||
@@ -2454,7 +2454,7 @@ add_library(LIB_5GNAS_GNB
|
||||
${NAS_SRC}/NR_UE/ue_process_nas.c
|
||||
${OPENAIR3_DIR}//UICC/usim_interface.c
|
||||
)
|
||||
target_link_libraries(LIB_5GNAS_GNB SECU_CN)
|
||||
target_link_libraries(LIB_5GNAS_GNB SECU_CN ${CRYPTO_LIBRARIES})
|
||||
|
||||
# Make lfds as a own source code (even if it is a outside library)
|
||||
# For better intergration with compilation flags & structure of cmake
|
||||
@@ -2809,6 +2809,7 @@ add_executable(nr-softmodem
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_DIR}/executables/nr-gnb.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/executables/nr-ru.c
|
||||
${OPENAIR_DIR}/executables/nr-softmodem.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
@@ -3112,6 +3113,7 @@ target_link_libraries(nr_prachsim
|
||||
|
||||
add_executable(nr_ulschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
@@ -3126,6 +3128,7 @@ target_link_libraries(nr_ulschsim
|
||||
|
||||
add_executable(nr_ulsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project (OpenAirInterface)
|
||||
set ( CMAKE_BUILD_TYPE )
|
||||
set ( CFLAGS_PROCESSOR_USER "" )
|
||||
set ( UE_EXPANSION False )
|
||||
set ( PRE_SCD_THREAD False )
|
||||
set ( UESIM_EXPANSION False )
|
||||
set ( ENABLE_VCD_FIFO False )
|
||||
set ( RF_BOARD "OAI_USRP")
|
||||
set ( RF_BOARD "None")
|
||||
set ( TRANSP_PRO "None")
|
||||
set ( PACKAGE_NAME "")
|
||||
set ( DEADLINE_SCHEDULER "False" )
|
||||
|
||||
+25
-1
@@ -100,13 +100,37 @@ Some other useful paramters of the UE are
|
||||
- --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.
|
||||
|
||||
## do-ra setup with OAI
|
||||
|
||||
The do-ra flag is used to ran the NR Random Access procedures in contention-free mode. Currently OAI implements the RACH process from Msg1 to Msg3.
|
||||
|
||||
In order to run the RA, the following flag is needed for both the gNB and the UE:
|
||||
|
||||
`--do-ra`
|
||||
|
||||
### Run OAI in do-ra mode
|
||||
|
||||
From the `cmake_targets/ran_build/build` folder:
|
||||
|
||||
gNB on machine 1:
|
||||
|
||||
`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --do-ra`
|
||||
|
||||
UE on machine 2:
|
||||
|
||||
`sudo ./nr-uesoftmodem --do-ra`
|
||||
|
||||
With the RF simulator (on the same machine):
|
||||
|
||||
`sudo RFSIMULATOR=gnb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD`
|
||||
|
||||
`sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD`
|
||||
|
||||
|
||||
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
|
||||
|
||||
+35
-13
@@ -597,6 +597,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
int i;
|
||||
struct timespec abstime;
|
||||
int time_ns = 50000;
|
||||
int wait_timer = 0;
|
||||
bool do_last_check = 1;
|
||||
|
||||
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
|
||||
for (i=0; i<gNB->num_RU; i++) {
|
||||
@@ -617,22 +619,36 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
|
||||
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret);
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &abstime);
|
||||
abstime.tv_nsec = abstime.tv_nsec + time_ns;
|
||||
|
||||
if (abstime.tv_nsec >= 1000*1000*1000) {
|
||||
abstime.tv_nsec -= 1000*1000*1000;
|
||||
abstime.tv_sec += 1;
|
||||
}
|
||||
|
||||
// wake up TX for subframe n+sf_ahead
|
||||
// lock the TX mutex and make sure the thread is ready
|
||||
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
|
||||
while (wait_timer < 200) {
|
||||
clock_gettime(CLOCK_REALTIME, &abstime);
|
||||
abstime.tv_nsec = abstime.tv_nsec + time_ns;
|
||||
|
||||
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
|
||||
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
|
||||
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
|
||||
return(-1);
|
||||
if (abstime.tv_nsec >= 1000*1000*1000) {
|
||||
abstime.tv_nsec -= 1000*1000*1000;
|
||||
abstime.tv_sec += 1;
|
||||
}
|
||||
|
||||
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
|
||||
|
||||
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so wait for a bit
|
||||
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
|
||||
wait_timer += 50;
|
||||
usleep(50);
|
||||
}
|
||||
else {
|
||||
do_last_check = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (do_last_check) {
|
||||
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
|
||||
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
|
||||
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
|
||||
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
++L1_proc->instance_cnt;
|
||||
@@ -845,6 +861,12 @@ void init_gNB_proc(int inst) {
|
||||
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
|
||||
pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
|
||||
sync_phy_proc.phy_proc_CC_id = 0;
|
||||
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
char ul_pool[] = "-1,-1";
|
||||
initTpool(ul_pool, gNB->threadPool, false);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+18
-1
@@ -420,7 +420,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
|
||||
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
|
||||
#else
|
||||
uint64_t a=rdtsc();
|
||||
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
|
||||
phy_procedures_nrUE_RX( UE, proc, 0, UE->mode);
|
||||
LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
|
||||
//printf(">>> nr_ue_pdcch_procedures ended\n");
|
||||
#endif
|
||||
@@ -839,6 +839,23 @@ void init_NR_UE(int nb_inst, char* rrc_config_path) {
|
||||
AssertFatal((rrc_inst = nr_l3_init_ue(rrc_config_path)) != NULL, "can not initialize RRC module\n");
|
||||
AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
|
||||
AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
|
||||
|
||||
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
|
||||
if (mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
|
||||
pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
|
||||
}
|
||||
else if (mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
|
||||
pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
}
|
||||
|
||||
if (pusch_TimeDomainAllocationList) {
|
||||
for(int i = 0; i < pusch_TimeDomainAllocationList->list.count; i++) {
|
||||
AssertFatal(*pusch_TimeDomainAllocationList->list.array[i]->k2 >= DURATION_RX_TO_TX,
|
||||
"Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n",
|
||||
*pusch_TimeDomainAllocationList->list.array[i]->k2,
|
||||
DURATION_RX_TO_TX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -415,8 +415,14 @@ typedef struct {
|
||||
uint8_t number_of_candidates;
|
||||
uint16_t CCE[64];
|
||||
uint8_t L[64];
|
||||
uint8_t dci_length;
|
||||
uint8_t dci_format;
|
||||
// 3GPP TS 38.212 Sec. 7.3.1.0, 3GPP TS 138.131 sec. 6.3.2 (SearchSpace)
|
||||
// The maximum number of DCI lengths allowed by the spec are 4, with max 3 for C-RNTI.
|
||||
// But a given search space may only support a maximum of 2 DCI formats at a time
|
||||
// depending on its search space type configured by RRC. Hence for blind decoding, UE
|
||||
// needs to monitor only upto 2 DCI lengths for a given search space.
|
||||
uint8_t num_dci_options; // Num DCIs the UE actually needs to decode (1 or 2)
|
||||
uint8_t dci_length_options[2];
|
||||
uint8_t dci_format_options[2];
|
||||
} fapi_nr_dl_config_dci_dl_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -469,6 +469,9 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
||||
unsigned int *F,
|
||||
uint8_t BG);
|
||||
|
||||
/*!\fn uint32_t nr_compute_tbs
|
||||
\brief This function returns the TBS in bits as per 6.1.4.2 of TS 38.214
|
||||
*/
|
||||
uint32_t nr_compute_tbs(uint16_t Qm,
|
||||
uint16_t R,
|
||||
uint16_t nb_rb,
|
||||
@@ -480,8 +483,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
|
||||
|
||||
uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
uint16_t nb_rb,
|
||||
uint8_t Nl,
|
||||
uint8_t C);
|
||||
uint8_t Nl);
|
||||
|
||||
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (E + F <= Ncb-ind) { //E+F doesn't contain all coded bits
|
||||
if (E <= Ncb-ind) { //E+F doesn't contain all coded bits
|
||||
memcpy((void*)(e),(void*)(w+ind),E);
|
||||
k=E;
|
||||
}
|
||||
|
||||
@@ -264,11 +264,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
for (i=0; i<Prx; i++) {
|
||||
pusch_vars[ULSCH_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot); // symbols per slot
|
||||
pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
|
||||
|
||||
@@ -39,95 +39,6 @@
|
||||
//#define DEBUG_DCI
|
||||
//#define DEBUG_CHANNEL_CODING
|
||||
|
||||
|
||||
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
|
||||
nfapi_nr_rnti_type_e rnti_type,
|
||||
uint16_t N_RB) {
|
||||
uint16_t size = 0;
|
||||
|
||||
switch(format) {
|
||||
/*Only sizes for 0_0 and 1_0 are correct at the moment*/
|
||||
case NFAPI_NR_UL_DCI_FORMAT_0_0:
|
||||
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
|
||||
size += 20;
|
||||
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
|
||||
size += nr_get_dci_size(NFAPI_NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB) - size; // Padding to match 1_0 size
|
||||
// UL/SUL indicator assumed to be 0
|
||||
break;
|
||||
|
||||
case NFAPI_NR_UL_DCI_FORMAT_0_1:
|
||||
/// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, SRS request 2 --17
|
||||
size += 17;
|
||||
// Carrier indicator
|
||||
// UL/SUL indicator
|
||||
// BWP Indicator
|
||||
// Freq domain assignment
|
||||
// Time domain assignment
|
||||
// VRB to PRB mapping
|
||||
// Frequency Hopping flag
|
||||
// 1st DAI
|
||||
// 2nd DAI
|
||||
// SRS resource indicator
|
||||
// Precoding info and number of layers
|
||||
// Antenna ports
|
||||
// CSI request
|
||||
// CBGTI
|
||||
// PTRS - DMRS association
|
||||
// beta offset indicator
|
||||
// DMRS sequence init
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_1_0:
|
||||
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
|
||||
size += 28;
|
||||
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_1_1:
|
||||
// Carrier indicator
|
||||
size += 1; // Format identifier
|
||||
// BWP Indicator
|
||||
// Freq domain assignment
|
||||
// Time domain assignment
|
||||
// VRB to PRB mapping
|
||||
// PRB bundling size indicator
|
||||
// Rate matching indicator
|
||||
// ZP CSI-RS trigger
|
||||
/// TB1- MCS 5, NDI 1, RV 2
|
||||
size += 8;
|
||||
// TB2
|
||||
size += 4 ; // HARQ PID
|
||||
// DAI
|
||||
size += 2; // TPC PUCCH
|
||||
size += 3; // PUCCH resource indicator
|
||||
size += 3; // PDSCH to HARQ timing indicator
|
||||
// Antenna ports
|
||||
// Tx Config Indication
|
||||
size += 2; // SRS request
|
||||
// CBGTI
|
||||
// CBGFI
|
||||
size += 1; // DMRS sequence init
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_0:
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_1:
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_2:
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_3:
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0, "Invalid NR DCI format %d\n", format);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void nr_pdcch_scrambling(uint32_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
|
||||
@@ -527,7 +527,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
if (rel15->nrOfLayers < Nl)
|
||||
Nl = rel15->nrOfLayers;
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
|
||||
|
||||
start_meas(dlsch_rate_matching_stats);
|
||||
nr_rate_matching_ldpc(Ilbrm,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL);
|
||||
|
||||
|
||||
@@ -52,9 +52,6 @@
|
||||
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
|
||||
//#define PRINT_CRC_CHECK
|
||||
|
||||
static uint64_t nb_total_decod =0;
|
||||
static uint64_t nb_error_decod =0;
|
||||
|
||||
//extern double cpuf;
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
|
||||
@@ -286,7 +283,177 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
|
||||
static uint32_t prnt_crc_cnt = 0;
|
||||
#endif
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
void nr_processULSegment(void* arg) {
|
||||
ldpcDecode_t *rdata = (ldpcDecode_t*) arg;
|
||||
PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
|
||||
int length_dec;
|
||||
int no_iteration_ldpc;
|
||||
int Kr;
|
||||
int Kr_bytes;
|
||||
int K_bytes_F;
|
||||
uint8_t crc_type;
|
||||
int i;
|
||||
int j;
|
||||
int r = rdata->segment_r;
|
||||
int A = rdata->A;
|
||||
int E = rdata->E;
|
||||
int Qm = rdata->Qm;
|
||||
int rv_index = rdata->rv_index;
|
||||
int r_offset = rdata->r_offset;
|
||||
uint8_t kc = rdata->Kc;
|
||||
uint32_t Tbslbrm = rdata->Tbslbrm;
|
||||
short* ulsch_llr = rdata->ulsch_llr;
|
||||
int max_ldpc_iterations = p_decoderParms->numMaxIter;
|
||||
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
|
||||
|
||||
int16_t z [68*384];
|
||||
int8_t l [68*384];
|
||||
|
||||
__m128i *pv = (__m128i*)&z;
|
||||
__m128i *pl = (__m128i*)&l;
|
||||
|
||||
uint8_t Ilbrm = 0;
|
||||
|
||||
Kr = ulsch_harq->K;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
K_bytes_F = Kr_bytes-(ulsch_harq->F>>3);
|
||||
|
||||
t_nrLDPC_time_stats procTime;
|
||||
t_nrLDPC_time_stats* p_procTime = &procTime ;
|
||||
|
||||
//start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////// ulsch_llr =====> ulsch_harq->e //////////////////////////////
|
||||
|
||||
nr_deinterleaving_ldpc(E,
|
||||
Qm,
|
||||
ulsch_harq->e[r],
|
||||
ulsch_llr+r_offset);
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset);
|
||||
|
||||
stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
|
||||
/*LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||
harq_pid,r, G,
|
||||
Kr*3,
|
||||
ulsch_harq->TBS,
|
||||
Qm,
|
||||
nb_rb,
|
||||
n_layers,
|
||||
pusch_pdu->pusch_data.rv_index,
|
||||
ulsch_harq->round);*/
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////// ulsch_harq->e =====> ulsch_harq->d /////////////////////////
|
||||
|
||||
//start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
p_decoderParms->BG,
|
||||
p_decoderParms->Z,
|
||||
ulsch_harq->d[r],
|
||||
ulsch_harq->e[r],
|
||||
ulsch_harq->C,
|
||||
rv_index,
|
||||
(ulsch_harq->round==0)?1:0,
|
||||
E,
|
||||
ulsch_harq->F,
|
||||
Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
|
||||
|
||||
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
|
||||
rdata->decodeIterations = max_ldpc_iterations + 1;
|
||||
return;
|
||||
} else {
|
||||
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
|
||||
}
|
||||
|
||||
memset(ulsch_harq->c[r],0,Kr_bytes);
|
||||
|
||||
if (ulsch_harq->C == 1) {
|
||||
if (A > 3824)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC16;
|
||||
|
||||
length_dec = ulsch_harq->B;
|
||||
}
|
||||
else {
|
||||
crc_type = CRC24_B;
|
||||
length_dec = (ulsch_harq->B+24*ulsch_harq->C)/ulsch_harq->C;
|
||||
}
|
||||
|
||||
//start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
||||
|
||||
memset(pv,0,2*ulsch_harq->Z*sizeof(int16_t));
|
||||
memset((pv+K_bytes_F),127,ulsch_harq->F*sizeof(int16_t));
|
||||
|
||||
for (i=((2*p_decoderParms->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
|
||||
}
|
||||
|
||||
AssertFatal(kc!=255,"");
|
||||
j+=(ulsch_harq->F>>3);
|
||||
for (i=Kr_bytes; i < ((kc*p_decoderParms->Z)>>3); i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
|
||||
}
|
||||
|
||||
for (i=0, j=0; j < ((kc*p_decoderParms->Z)>>4); i+=2, j++) {
|
||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
|
||||
(int8_t*)&pl[0],
|
||||
llrProcBuf,
|
||||
ulsch_harq->p_nrLDPC_procBuf[r],
|
||||
p_procTime);
|
||||
|
||||
if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
LOG_I(PHY, "Segment %d CRC OK\n",r);
|
||||
#endif
|
||||
rdata->decodeIterations = no_iteration_ldpc;
|
||||
} else {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
LOG_I(PHY, "CRC NOK\n");
|
||||
#endif
|
||||
rdata->decodeIterations = max_ldpc_iterations + 1;
|
||||
}
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++) {
|
||||
ulsch_harq->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
}
|
||||
|
||||
//stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
||||
}
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t UE_id,
|
||||
short *ulsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -296,36 +463,36 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
uint8_t harq_pid,
|
||||
uint32_t G) {
|
||||
|
||||
uint32_t A,E;
|
||||
uint32_t ret, offset;
|
||||
int32_t no_iteration_ldpc, length_dec;
|
||||
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
|
||||
uint8_t crc_type;
|
||||
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
|
||||
uint32_t A;
|
||||
uint32_t r;
|
||||
uint32_t r_offset;
|
||||
uint32_t offset;
|
||||
int kc;
|
||||
int Tbslbrm;
|
||||
int E;
|
||||
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
prnt_crc_cnt++;
|
||||
#endif
|
||||
|
||||
|
||||
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[UE_id][0];
|
||||
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
|
||||
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
|
||||
|
||||
t_nrLDPC_dec_params decParams;
|
||||
t_nrLDPC_dec_params* p_decParams = &decParams;
|
||||
t_nrLDPC_time_stats procTime;
|
||||
t_nrLDPC_time_stats* p_procTime = &procTime ;
|
||||
if (!harq_process) {
|
||||
printf("ulsch_decoding.c: NULL harq_process pointer\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
}
|
||||
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
|
||||
|
||||
int16_t z [68*384];
|
||||
int8_t l [68*384];
|
||||
uint8_t kc = 255;
|
||||
uint8_t Ilbrm = 0;
|
||||
uint32_t Tbslbrm = 950984;
|
||||
int Kr;
|
||||
int Kr_bytes;
|
||||
|
||||
phy_vars_gNB->nbDecode = 0;
|
||||
harq_process->processedSegments = 0;
|
||||
|
||||
if (!harq_process) {
|
||||
LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
double Coderate = 0.0;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@@ -336,30 +503,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
uint8_t n_layers = pusch_pdu->nrOfLayers;
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
uint32_t i,j;
|
||||
|
||||
__m128i *pv = (__m128i*)&z;
|
||||
__m128i *pl = (__m128i*)&l;
|
||||
|
||||
|
||||
if (!ulsch_llr) {
|
||||
printf("ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!frame_parms) {
|
||||
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
}
|
||||
|
||||
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
|
||||
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
|
||||
harq_process->round = nr_rv_round_map[pusch_pdu->pusch_data.rv_index];
|
||||
|
||||
A = (harq_process->TBS)<<3;
|
||||
ret = ulsch->max_ldpc_iterations + 1;
|
||||
|
||||
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
|
||||
|
||||
@@ -401,12 +554,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
NR_gNB_SCH_STATS_t *stats=NULL;
|
||||
int first_free=-1;
|
||||
for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++) {
|
||||
if (gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
|
||||
if (phy_vars_gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
|
||||
first_free = i;
|
||||
stats=&gNB->ulsch_stats[i];
|
||||
stats=&phy_vars_gNB->ulsch_stats[i];
|
||||
}
|
||||
if (gNB->ulsch_stats[i].rnti == ulsch->rnti) {
|
||||
stats=&gNB->ulsch_stats[i];
|
||||
if (phy_vars_gNB->ulsch_stats[i].rnti == ulsch->rnti) {
|
||||
stats=&phy_vars_gNB->ulsch_stats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -420,13 +573,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
stats->current_RI = n_layers;
|
||||
stats->total_bytes_tx += harq_process->TBS;
|
||||
}
|
||||
// This is a new packet, so compute quantities regarding segmentation
|
||||
if (A > 3824)
|
||||
harq_process->B = A+24;
|
||||
else
|
||||
harq_process->B = A+16;
|
||||
}
|
||||
if (A > 3824)
|
||||
harq_process->B = A+24;
|
||||
else
|
||||
harq_process->B = A+16;
|
||||
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
harq_process->B,
|
||||
@@ -437,18 +590,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
p_decParams->BG);
|
||||
|
||||
#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("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);
|
||||
#endif
|
||||
}
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers);
|
||||
|
||||
p_decParams->Z = harq_process->Z;
|
||||
|
||||
|
||||
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
|
||||
p_decParams->outMode= 0;
|
||||
|
||||
err_flag = 0;
|
||||
r_offset = 0;
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
|
||||
@@ -460,284 +613,48 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
|
||||
if (harq_process->C > a_segments) {
|
||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
return 1;
|
||||
}
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
#endif
|
||||
|
||||
//opp_enabled=1;
|
||||
|
||||
Kr = harq_process->K;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
K_bytes_F = Kr_bytes-(harq_process->F>>3);
|
||||
offset = 0;
|
||||
void (*nr_processULSegment_ptr)(void*) = &nr_processULSegment;
|
||||
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
|
||||
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
|
||||
|
||||
union ldpcReqUnion id = {.s={ulsch->rnti,frame,nr_tti_rx,0,0}};
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, phy_vars_gNB->respDecode, nr_processULSegment_ptr);
|
||||
ldpcDecode_t * rdata=(ldpcDecode_t *) NotifiedFifoData(req);
|
||||
|
||||
start_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
|
||||
|
||||
nr_deinterleaving_ldpc(E,
|
||||
Qm,
|
||||
harq_process->e[r],
|
||||
ulsch_llr+r_offset);
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
|
||||
|
||||
stop_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
|
||||
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rvidx %d, round %d)...\n",
|
||||
harq_pid,r, G,
|
||||
Kr*3,
|
||||
harq_process->TBS,
|
||||
Qm,
|
||||
nb_rb,
|
||||
n_layers,
|
||||
pusch_pdu->pusch_data.rv_index,
|
||||
harq_process->round);
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
|
||||
|
||||
start_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
p_decParams->BG,
|
||||
p_decParams->Z,
|
||||
harq_process->d[r],
|
||||
harq_process->e[r],
|
||||
harq_process->C,
|
||||
pusch_pdu->pusch_data.rv_index,
|
||||
(harq_process->round==0)?1:0,
|
||||
E,
|
||||
harq_process->F,
|
||||
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
|
||||
|
||||
stop_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
} else {
|
||||
stop_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
}
|
||||
|
||||
rdata->gNB = phy_vars_gNB;
|
||||
rdata->ulsch_harq = harq_process;
|
||||
rdata->decoderParms = decParams;
|
||||
rdata->ulsch_llr = ulsch_llr;
|
||||
rdata->Kc = kc;
|
||||
rdata->harq_pid = harq_pid;
|
||||
rdata->segment_r = r;
|
||||
rdata->nbSegments = harq_process->C;
|
||||
rdata->E = E;
|
||||
rdata->A = A;
|
||||
rdata->Qm = Qm;
|
||||
rdata->r_offset = r_offset;
|
||||
rdata->Kr_bytes = Kr_bytes;
|
||||
rdata->rv_index = pusch_pdu->pusch_data.rv_index;
|
||||
rdata->Tbslbrm = Tbslbrm;
|
||||
rdata->offset = offset;
|
||||
rdata->ulsch = ulsch;
|
||||
rdata->ulsch_id = UE_id;
|
||||
pushTpool(phy_vars_gNB->threadPool,req);
|
||||
phy_vars_gNB->nbDecode++;
|
||||
LOG_D(PHY,"Added a block to decode, in pipe: %d\n",phy_vars_gNB->nbDecode);
|
||||
r_offset += E;
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
if (r==0) {
|
||||
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
|
||||
write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
|
||||
}
|
||||
|
||||
printf("decoder input(segment %u) :", r);
|
||||
int i;
|
||||
for (i=0;i<(3*8*Kr_bytes)+12;i++)
|
||||
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
|
||||
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||
memset(harq_process->c[r],0,Kr_bytes);
|
||||
|
||||
// printf("done\n");
|
||||
if (harq_process->C == 1) {
|
||||
if (A > 3824)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC16;
|
||||
|
||||
length_dec = harq_process->B;
|
||||
}
|
||||
else {
|
||||
crc_type = CRC24_B;
|
||||
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
|
||||
}
|
||||
|
||||
if (err_flag == 0) {
|
||||
|
||||
start_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
|
||||
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
|
||||
|
||||
|
||||
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
|
||||
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
|
||||
|
||||
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
|
||||
}
|
||||
|
||||
AssertFatal(kc!=255,"");
|
||||
j+=(harq_process->F>>3);
|
||||
for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
|
||||
}
|
||||
|
||||
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
|
||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||
(int8_t*)&pl[0],
|
||||
llrProcBuf,
|
||||
p_nrLDPC_procBuf[r],
|
||||
p_procTime);
|
||||
|
||||
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
//if (prnt_crc_cnt % 10 == 0)
|
||||
LOG_I(PHY, "Segment %d CRC OK\n",r);
|
||||
#endif
|
||||
ret = no_iteration_ldpc;
|
||||
} else {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
//if (prnt_crc_cnt%10 == 0)
|
||||
LOG_I(PHY, "CRC NOK\n");
|
||||
#endif
|
||||
ret = ulsch->max_ldpc_iterations + 1;
|
||||
}
|
||||
nb_total_decod++;
|
||||
|
||||
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
|
||||
nb_error_decod++;
|
||||
}
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++) {
|
||||
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
for (int k=0;k<A>>3;k++)
|
||||
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
|
||||
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
|
||||
#endif
|
||||
|
||||
stop_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
}
|
||||
|
||||
if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) {
|
||||
// a Code segment is in error so break;
|
||||
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
|
||||
err_flag = 1;
|
||||
}
|
||||
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
int32_t frame_rx_prev = frame;
|
||||
int32_t tti_rx_prev = nr_tti_rx - 1;
|
||||
if (tti_rx_prev < 0) {
|
||||
frame_rx_prev--;
|
||||
tti_rx_prev += frame_parms->slots_per_frame;
|
||||
}
|
||||
frame_rx_prev = frame_rx_prev%1024;
|
||||
|
||||
if (err_flag == 1) {
|
||||
|
||||
#ifdef gNB_DEBUG_TRACE
|
||||
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n",
|
||||
gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r);
|
||||
#endif
|
||||
|
||||
// harq_process->harq_ack.ack = 0;
|
||||
// harq_process->harq_ack.harq_id = harq_pid;
|
||||
// harq_process->harq_ack.send_harq_status = 1;
|
||||
// harq_process->errors[harq_process->round]++;
|
||||
//harq_process->round++;
|
||||
|
||||
if (harq_process->round >= ulsch->Mlimit) {
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
harq_process->handled = 0;
|
||||
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",
|
||||
// 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;
|
||||
|
||||
} else {
|
||||
|
||||
#ifdef gNB_DEBUG_TRACE
|
||||
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
|
||||
gNB->Mod_id,nr_tti_rx,harq_process->TBS);
|
||||
#endif
|
||||
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
// harq_process->handled = 0;
|
||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
||||
// harq_process->harq_ack.ack = 1;
|
||||
// harq_process->harq_ack.harq_id = harq_pid;
|
||||
// harq_process->harq_ack.send_harq_status = 1;
|
||||
|
||||
// LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",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;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
|
||||
memcpy(harq_process->b+offset,
|
||||
harq_process->c[r],
|
||||
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
|
||||
|
||||
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("Segment %u : Kr = %u bytes\n", r, Kr_bytes);
|
||||
printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)), harq_pid);
|
||||
printf("b[0] = %x, c[%d] = %x\n", harq_process->b[offset], harq_process->F>>3, harq_process->c[r]);
|
||||
#endif
|
||||
|
||||
}
|
||||
if (stats) stats->total_bytes_rx += harq_process->TBS;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
LOG_I(PHY, "Decoder output (payload) at SFN/SF: %d/%d TBS: %d\n", frame, nr_tti_rx,harq_process->TBS);
|
||||
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("%02x ",harq_process->b[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
ulsch->last_iteration_cnt = ret;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
|
||||
return(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
|
||||
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
|
||||
uci_pdu->harq->harq_list[0].harq_value = index&0x01;
|
||||
LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
LOG_D(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
|
||||
if (pucch_pdu->sr_flag == 1) {
|
||||
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
||||
@@ -429,7 +429,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
|
||||
uci_pdu->harq->harq_list[1].harq_value = index&0x01;
|
||||
uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
|
||||
LOG_I(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
LOG_D(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
|
||||
if (pucch_pdu->sr_flag == 1) {
|
||||
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
||||
|
||||
@@ -845,7 +845,6 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
for (int i=0;i<pdcch_vars->nb_search_space;i++) {
|
||||
|
||||
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;
|
||||
@@ -853,41 +852,47 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
for (int j=0;j<rel15->number_of_candidates;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(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
|
||||
|
||||
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);
|
||||
// Loop over possible DCI lengths
|
||||
for (int k = 0; k < rel15->num_dci_options; k++) {
|
||||
int dci_length = rel15->dci_length_options[k];
|
||||
uint64_t dci_estimation[2]= {0};
|
||||
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
|
||||
|
||||
nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
|
||||
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);
|
||||
|
||||
#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]));
|
||||
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);
|
||||
|
||||
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_options[k]);
|
||||
dci_ind->SFN = frame;
|
||||
dci_ind->slot = slot;
|
||||
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_options[k];
|
||||
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++;
|
||||
break; // If DCI is found, no need to check for remaining DCI lengths
|
||||
} else {
|
||||
LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t crc = polar_decoder_int16(tmp_e,
|
||||
dci_estimation,
|
||||
1,
|
||||
currentPtrDCI);
|
||||
|
||||
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 = 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,9 +478,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
|
||||
|
||||
if ((harq_process->Nl)<4)
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
|
||||
else
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
|
||||
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
@@ -1069,7 +1069,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
if (harq_process->Nl < Nl)
|
||||
Nl = harq_process->Nl;
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
@@ -1610,9 +1610,9 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
#endif
|
||||
|
||||
if (Nl<4)
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
|
||||
else
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
|
||||
@@ -53,11 +53,9 @@ int16_t nr_dlsch_demod_shift = 0;
|
||||
//int16_t interf_unaw_shift = 13;
|
||||
|
||||
//#define DEBUG_HARQ
|
||||
|
||||
//#define DEBUG_PHY 1
|
||||
//#define DEBUG_DLSCH_DEMOD 1
|
||||
|
||||
|
||||
//#define DEBUG_PHY
|
||||
//#define DEBUG_DLSCH_DEMOD
|
||||
//#define DEBUG_PDSCH_RX
|
||||
|
||||
// [MCS][i_mod (0,1,2) = (2,4,6)]
|
||||
//unsigned char offset_mumimo_llr_drange_fix=0;
|
||||
@@ -188,7 +186,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
if (dlsch0_harq && dlsch1_harq){
|
||||
|
||||
//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 ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){
|
||||
@@ -1042,42 +1039,30 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Please keep it: useful for debugging
|
||||
#if 0
|
||||
if( (symbol == 13) && (nr_tti_rx==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/)
|
||||
{
|
||||
LOG_E(PHY,"Dump Phy Chan Est \n");
|
||||
if(1)
|
||||
{
|
||||
#if 1
|
||||
write_output("rxdataF0.m" , "rxdataF0", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("rxdataF1.m" , "rxdataF1", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
write_output("dl_ch_estimates00.m", "dl_ch_estimates00", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("dl_ch_estimates01.m", "dl_ch_estimates01", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("dl_ch_estimates10.m", "dl_ch_estimates10", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("dl_ch_estimates11.m", "dl_ch_estimates11", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
#ifdef DEBUG_PDSCH_RX
|
||||
char filename[40];
|
||||
uint8_t aa = 0;
|
||||
|
||||
snprintf(filename, 40, "rxdataF0_symb_%d_nr_tti_rx_%d.m", symbol, nr_tti_rx);
|
||||
write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
|
||||
|
||||
//write_output("rxdataF_ext00.m" , "rxdataF_ext00", &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_ext01.m" , "rxdataF_ext01", &pdsch_vars[eNB_id]->rxdataF_ext[1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_ext10.m" , "rxdataF_ext10", &pdsch_vars[eNB_id]->rxdataF_ext[2][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_ext11.m" , "rxdataF_ext11", &pdsch_vars[eNB_id]->rxdataF_ext[3][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("dl_ch_estimates_ext01.m", "dl_ch_estimates_ext01", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("dl_ch_estimates_ext10.m", "dl_ch_estimates_ext10", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[2][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("dl_ch_estimates_ext11.m", "dl_ch_estimates_ext11", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[3][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
write_output("rxdataF_comp00.m","rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_comp01.m","rxdataF_comp01", &pdsch_vars[eNB_id]->rxdataF_comp0[1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_comp10.m","rxdataF_comp10", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_comp11.m","rxdataF_comp11", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
#endif
|
||||
write_output("llr0.m","llr0", &pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
|
||||
//write_output("llr1.m","llr1", &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
|
||||
snprintf(filename, 40, "dl_ch_estimates0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "dl_ch_estimates", &pdsch_vars[eNB_id]->dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
|
||||
|
||||
snprintf(filename, 40, "rxdataF_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "rxdataF_ext", &pdsch_vars[eNB_id]->rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
|
||||
|
||||
AssertFatal(0," ");
|
||||
}
|
||||
snprintf(filename, 40, "dl_ch_estimates_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
|
||||
|
||||
snprintf(filename, 40, "rxdataF_comp0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
|
||||
|
||||
for (int i=0; i < 2; i++){
|
||||
snprintf(filename, 40, "llr%d_symb_%d_nr_tti_rx_%d.m", i, symbol, nr_tti_rx);
|
||||
write_output(filename,"llr", &pdsch_vars[eNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm), 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2572,51 +2557,51 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int *
|
||||
char fname[32],vname[32];
|
||||
int N_RB_DL=ue->frame_parms.N_RB_DL;
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_ext0",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
if (ue->frame_parms.nb_antennas_rx >1) {
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_ext1",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_ext1",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext00.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext00",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext00.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext00",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
if (ue->transmission_mode[eNB_id]==7){
|
||||
sprintf(fname,"dlsch%d_bf_ch_r%d.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_bf_ch_r%d",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_bf_ch_r%d.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_bf_ch_r%d",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
|
||||
//write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1);
|
||||
|
||||
sprintf(fname,"dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_bf_ch_r%d_ext00",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_bf_ch_r%d_ext00",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
if (ue->frame_parms.nb_antennas_rx == 2) {
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext01.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext01",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
if (ue->frame_parms.nb_antenna_ports_gNB == 2) {
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext10.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext10",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext10.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext10",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
if (ue->frame_parms.nb_antennas_rx == 2) {
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext11.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext11",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext11.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext11",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_uespec0",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
|
||||
|
||||
/*
|
||||
@@ -2624,33 +2609,33 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int *
|
||||
write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
|
||||
write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
|
||||
*/
|
||||
sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round);
|
||||
sprintf(vname,"dl_rho_r%d_%d",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_rho.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl_rho_r%d_%d",eNB_id,round);
|
||||
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round);
|
||||
sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_rho2.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl_rho2_r%d_%d",eNB_id,round);
|
||||
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_comp0",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
|
||||
if (ue->frame_parms.nb_antenna_ports_gNB == 2) {
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_comp1",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_r%d_llr",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_llr.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_r%d_llr",eNB_id,round);
|
||||
write_output(fname,vname, ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
|
||||
sprintf(fname,"dlsch%d_r%d_mag1.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_r%d_mag1",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_mag1.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_r%d_mag1",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
|
||||
sprintf(fname,"dlsch%d_r%d_mag2.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_r%d_mag2",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_mag2.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_r%d_mag2",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
// printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
|
||||
//#define DEBUG_ULSCH_CODING
|
||||
|
||||
void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL)
|
||||
|
||||
@@ -248,7 +249,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
crc = 1;
|
||||
harq_process = ulsch->harq_processes[harq_pid];
|
||||
nb_rb = harq_process->pusch_pdu.rb_size;
|
||||
A = harq_process->pusch_pdu.pusch_data.tb_size;
|
||||
A = harq_process->pusch_pdu.pusch_data.tb_size*8;
|
||||
pz = &Z;
|
||||
mod_order = nr_get_Qm_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
|
||||
R = nr_get_code_rate_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
|
||||
@@ -271,7 +272,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
// if (harq_process->Ndi == 1) { // this is a new packet
|
||||
if (harq_process->round == 0) { // this is a new packet
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("encoding thinks this is a new packet \n");
|
||||
#endif
|
||||
|
||||
@@ -345,7 +346,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
F = harq_process->F;
|
||||
Kr = harq_process->K;
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
uint16_t Kr_bytes;
|
||||
Kr_bytes = Kr>>3;
|
||||
#endif
|
||||
@@ -358,7 +359,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
//start_meas(te_stats);
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
//channel_input[r] = &harq_process->d[r][0];
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F);
|
||||
printf("start ldpc encoder segment %d/%d\n",r,harq_process->C);
|
||||
printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
@@ -391,6 +392,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
encoder_implemparams_t impp;
|
||||
impp.n_segments=harq_process->C;
|
||||
impp.macro_num=0;
|
||||
impp.tinput = NULL;
|
||||
impp.tprep = NULL;
|
||||
impp.tparity = NULL;
|
||||
impp.toutput = NULL;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
|
||||
|
||||
@@ -400,7 +405,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
//stop_meas(te_stats);
|
||||
//printf("end ldpc encoder -- output\n");
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
|
||||
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
|
||||
#endif
|
||||
@@ -438,7 +443,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
E = nr_get_E(G, harq_process->C, mod_order, harq_process->pusch_pdu.nrOfLayers, r);
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
|
||||
nr_rate_matching_ldpc(Ilbrm,
|
||||
@@ -456,7 +461,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output ratematching e[%d]= %d r_offset %d\n", i,harq_process->e[i+r_offset], r_offset);
|
||||
#endif
|
||||
@@ -482,7 +487,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
//stop_meas(i_stats);
|
||||
|
||||
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output interleaving f[%d]= %d r_offset %d\n", i,harq_process->f[i+r_offset], r_offset);
|
||||
|
||||
|
||||
@@ -101,74 +101,53 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
|
||||
|
||||
uint32_t available_bits;
|
||||
uint8_t mod_order, cwd_index, num_of_codewords, l;
|
||||
uint8_t cwd_index, l;
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
uint32_t ***pusch_dmrs;
|
||||
int16_t **tx_layers;
|
||||
int32_t **txdataF;
|
||||
uint16_t start_sc, start_rb;
|
||||
int8_t Wf[2], Wt[2], l_prime[2], delta;
|
||||
uint16_t rnti, n_dmrs, code_rate, number_dmrs_symbols, nb_rb, k;
|
||||
uint8_t dmrs_type, nb_dmrs_re_per_rb, number_of_symbols, mcs, Nl;
|
||||
int ap, start_symbol, Nid_cell, i;
|
||||
int sample_offsetF, N_RE_prime, N_PRB_oh;
|
||||
uint16_t ul_dmrs_symb_pos;
|
||||
uint8_t L_ptrs, K_ptrs; // PTRS parameters
|
||||
uint16_t beta_ptrs; // PTRS parameter related to power control
|
||||
uint8_t nb_dmrs_re_per_rb;
|
||||
int ap, i;
|
||||
int sample_offsetF, N_RE_prime;
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue;
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
|
||||
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
|
||||
// ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
|
||||
|
||||
num_of_codewords = 1; // tmp assumption
|
||||
Nid_cell = 0;
|
||||
N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
number_dmrs_symbols = 0;
|
||||
uint8_t num_of_codewords = 1; // tmp assumption
|
||||
int Nid_cell = 0;
|
||||
int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
uint16_t 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];
|
||||
harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu;
|
||||
|
||||
start_symbol = harq_process_ul_ue->pusch_pdu.start_symbol_index;
|
||||
ul_dmrs_symb_pos = harq_process_ul_ue->pusch_pdu.ul_dmrs_symb_pos;
|
||||
number_of_symbols = harq_process_ul_ue->pusch_pdu.nr_of_symbols;
|
||||
dmrs_type = harq_process_ul_ue->pusch_pdu.dmrs_config_type;
|
||||
int start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
|
||||
uint8_t dmrs_type = pusch_pdu->dmrs_config_type;
|
||||
uint16_t start_rb = pusch_pdu->rb_start;
|
||||
uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
uint8_t Nl = pusch_pdu->nrOfLayers;
|
||||
uint8_t mod_order = pusch_pdu->qam_mod_order;
|
||||
uint16_t rnti = pusch_pdu->rnti;
|
||||
uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data;
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
|
||||
for (i = start_symbol; i < start_symbol + number_of_symbols; i++) {
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
number_dmrs_symbols += 1;
|
||||
|
||||
}
|
||||
|
||||
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)*harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data;
|
||||
get_num_re_dmrs(pusch_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols);
|
||||
|
||||
// TbD num_of_mod_symbols is set but never used
|
||||
N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
|
||||
|
||||
nb_rb = harq_process_ul_ue->pusch_pdu.rb_size;
|
||||
|
||||
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords;
|
||||
|
||||
mcs = harq_process_ul_ue->pusch_pdu.mcs_index;
|
||||
Nl = harq_process_ul_ue->pusch_pdu.nrOfLayers;
|
||||
mod_order = nr_get_Qm_ul(mcs, 0);
|
||||
code_rate = nr_get_code_rate_ul(mcs, 0);
|
||||
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = nr_compute_tbs(mod_order,
|
||||
code_rate,
|
||||
nb_rb,
|
||||
number_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
0,
|
||||
0,
|
||||
harq_process_ul_ue->pusch_pdu.nrOfLayers);
|
||||
|
||||
/////////////////////////ULSCH coding/////////////////////////
|
||||
///////////
|
||||
|
||||
@@ -210,14 +189,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/////////////////////////DMRS Modulation/////////////////////////
|
||||
///////////
|
||||
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
|
||||
n_dmrs = (nb_rb*((dmrs_type == pusch_dmrs_type1) ? 6:4)*number_dmrs_symbols);
|
||||
uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
|
||||
uint16_t n_dmrs = (start_rb+nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
|
||||
int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -227,9 +202,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
///////////
|
||||
|
||||
int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
|
||||
K_ptrs = 0; // just to avoid a warning
|
||||
uint8_t L_ptrs, K_ptrs = 0;
|
||||
uint16_t beta_ptrs = 1; // temp value until power control is implemented
|
||||
|
||||
if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
K_ptrs = harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density;
|
||||
L_ptrs = 1<<harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_time_density;
|
||||
@@ -274,11 +250,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {
|
||||
|
||||
if((ul_dmrs_symb_pos >> l) & 0x01)
|
||||
is_dmrs = 1;
|
||||
else
|
||||
is_dmrs = 0;
|
||||
|
||||
if (is_dmrs == 1)
|
||||
nb_re_dmrs_per_rb = nb_dmrs_re_per_rb;
|
||||
else
|
||||
nb_re_dmrs_per_rb = 0;
|
||||
@@ -303,64 +274,70 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
txdataF = UE->common_vars.txdataF;
|
||||
|
||||
start_rb = harq_process_ul_ue->pusch_pdu.rb_start;
|
||||
start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
for (ap=0; ap< Nl; ap++) {
|
||||
|
||||
uint8_t k_prime = 0;
|
||||
uint16_t m = 0;
|
||||
|
||||
// DMRS params for this ap
|
||||
get_Wt(Wt, ap, dmrs_type);
|
||||
get_Wf(Wf, ap, dmrs_type);
|
||||
delta = get_delta(ap, dmrs_type);
|
||||
|
||||
|
||||
uint8_t k_prime=0;
|
||||
uint8_t is_dmrs, is_ptrs, is_dmrs_symbol;
|
||||
uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
|
||||
|
||||
for (l=start_symbol; l<start_symbol+number_of_symbols; l++) {
|
||||
ptrs_idx = 0; // every PTRS symbol has a new gold sequence
|
||||
k = start_sc;
|
||||
n = 0;
|
||||
dmrs_idx = 0;
|
||||
|
||||
uint16_t k = start_sc;
|
||||
uint16_t n = 0;
|
||||
uint8_t is_dmrs_sym = 0;
|
||||
uint8_t is_ptrs_sym = 0;
|
||||
uint16_t dmrs_idx = 0, ptrs_idx = 0;
|
||||
|
||||
if ((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
is_dmrs_sym = 1;
|
||||
|
||||
if (pusch_pdu->transform_precoding == 1){ // if transform precoding is disabled
|
||||
if (dmrs_type == pusch_dmrs_type1)
|
||||
dmrs_idx = start_rb*6;
|
||||
else
|
||||
dmrs_idx = start_rb*4;
|
||||
} else {
|
||||
dmrs_idx = 0;
|
||||
}
|
||||
|
||||
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
|
||||
is_ptrs_sym = 1;
|
||||
nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) {
|
||||
|
||||
uint8_t is_dmrs = 0;
|
||||
uint8_t is_ptrs = 0;
|
||||
|
||||
sample_offsetF = l*frame_parms->ofdm_symbol_size + k;
|
||||
|
||||
is_dmrs = 0;
|
||||
is_ptrs = 0;
|
||||
is_dmrs_symbol = 0;
|
||||
|
||||
if((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
is_dmrs_symbol = 1;
|
||||
if (is_dmrs_sym) {
|
||||
if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size))
|
||||
is_dmrs = 1;
|
||||
}
|
||||
|
||||
if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS){
|
||||
|
||||
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols))
|
||||
} else if (is_ptrs_sym) {
|
||||
is_ptrs = is_ptrs_subcarrier(k,
|
||||
rnti,
|
||||
ap,
|
||||
dmrs_type,
|
||||
K_ptrs,
|
||||
nb_rb,
|
||||
harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
start_sc,
|
||||
frame_parms->ofdm_symbol_size);
|
||||
}
|
||||
|
||||
if (is_dmrs == 1) {
|
||||
|
||||
if (k == start_sc){
|
||||
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
}
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
|
||||
|
||||
@@ -378,16 +355,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
} else if (is_ptrs == 1) {
|
||||
|
||||
if (k == start_sc){
|
||||
nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
|
||||
}
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15;
|
||||
|
||||
ptrs_idx++;
|
||||
|
||||
} else if (!is_dmrs_symbol || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data,dmrs_type)) {
|
||||
} else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, cdm_grps_no_data, dmrs_type)) {
|
||||
|
||||
((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];
|
||||
@@ -412,8 +385,8 @@ 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;
|
||||
|
||||
+40
-1
@@ -263,6 +263,8 @@ typedef struct {
|
||||
int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||
uint32_t E;
|
||||
/// Number of segments processed so far
|
||||
uint32_t processedSegments;
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -475,7 +477,6 @@ typedef struct {
|
||||
uint8_t cl_done;
|
||||
} NR_gNB_PUSCH;
|
||||
|
||||
|
||||
/// Context data structure for RX/TX portion of slot processing
|
||||
typedef struct {
|
||||
/// Component Carrier index
|
||||
@@ -822,7 +823,45 @@ typedef struct PHY_VARS_gNB_s {
|
||||
time_stats_t rx_dft_stats;
|
||||
time_stats_t ulsch_freq_offset_estimation_stats;
|
||||
*/
|
||||
notifiedFIFO_t *respDecode;
|
||||
tpool_t *threadPool;
|
||||
int nbDecode;
|
||||
|
||||
} PHY_VARS_gNB;
|
||||
|
||||
typedef struct LDPCDecode_s {
|
||||
PHY_VARS_gNB *gNB;
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq;
|
||||
t_nrLDPC_dec_params decoderParms;
|
||||
NR_gNB_ULSCH_t *ulsch;
|
||||
short* ulsch_llr;
|
||||
int ulsch_id;
|
||||
int harq_pid;
|
||||
int rv_index;
|
||||
int A;
|
||||
int E;
|
||||
int Kc;
|
||||
int Qm;
|
||||
int Kr_bytes;
|
||||
int nbSegments;
|
||||
int segment_r;
|
||||
int r_offset;
|
||||
int offset;
|
||||
int Tbslbrm;
|
||||
int decodeIterations;
|
||||
} ldpcDecode_t;
|
||||
|
||||
struct ldpcReqId {
|
||||
uint16_t rnti;
|
||||
uint16_t frame;
|
||||
uint8_t subframe;
|
||||
uint8_t codeblock;
|
||||
uint16_t spare;
|
||||
} __attribute__((packed));
|
||||
|
||||
union ldpcReqUnion {
|
||||
struct ldpcReqId s;
|
||||
uint64_t p;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -912,10 +912,6 @@ 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];
|
||||
|
||||
NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
int turbo_iterations, turbo_cntl_iterations;
|
||||
|
||||
@@ -213,12 +213,74 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
|
||||
*/
|
||||
|
||||
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
|
||||
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
|
||||
int r = rdata->segment_r;
|
||||
|
||||
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
|
||||
ulsch_harq->processedSegments++;
|
||||
LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n",
|
||||
rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments);
|
||||
gNB->nbDecode--;
|
||||
LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode);
|
||||
|
||||
if (decodeSuccess) {
|
||||
memcpy(ulsch_harq->b+rdata->offset,
|
||||
ulsch_harq->c[r],
|
||||
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
|
||||
|
||||
} else {
|
||||
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
|
||||
int nb=abortTpool(gNB->threadPool, req->key);
|
||||
nb+=abortNotifiedFIFO(gNB->respDecode, req->key);
|
||||
gNB->nbDecode-=nb;
|
||||
LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
|
||||
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
|
||||
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
|
||||
ulsch_harq->processedSegments, nb, rdata->nbSegments);
|
||||
ulsch_harq->processedSegments=rdata->nbSegments;
|
||||
}
|
||||
}
|
||||
|
||||
// if all segments are done
|
||||
if (rdata->nbSegments == ulsch_harq->processedSegments) {
|
||||
if (decodeSuccess) {
|
||||
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
|
||||
gNB->Mod_id,ulsch_harq->slot,ulsch_harq->TBS);
|
||||
ulsch_harq->status = SCH_IDLE;
|
||||
ulsch_harq->round = 0;
|
||||
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
|
||||
|
||||
LOG_D(PHY, "ULSCH received ok \n");
|
||||
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0);
|
||||
} else {
|
||||
LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) r %d\n",
|
||||
gNB->Mod_id, ulsch_harq->frame, ulsch_harq->slot,
|
||||
rdata->harq_pid,ulsch_harq->status, ulsch_harq->round,ulsch_harq->TBS,r);
|
||||
if (ulsch_harq->round >= ulsch->Mlimit) {
|
||||
ulsch_harq->status = SCH_IDLE;
|
||||
ulsch_harq->round = 0;
|
||||
ulsch_harq->handled = 0;
|
||||
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
|
||||
}
|
||||
ulsch_harq->handled = 1;
|
||||
|
||||
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
|
||||
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1);
|
||||
}
|
||||
ulsch->last_iteration_cnt = rdata->decodeIterations;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
|
||||
{
|
||||
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 l, number_dmrs_symbols = 0;
|
||||
uint32_t G;
|
||||
uint16_t start_symbol, number_symbols, nb_re_dmrs;
|
||||
@@ -270,25 +332,22 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
|
||||
//----------------------------------------------------------
|
||||
|
||||
start_meas(&gNB->ulsch_decoding_stats);
|
||||
ret = nr_ulsch_decoding(gNB,
|
||||
ULSCH_id,
|
||||
gNB->pusch_vars[ULSCH_id]->llr,
|
||||
frame_parms,
|
||||
pusch_pdu,
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
harq_pid,
|
||||
G);
|
||||
stop_meas(&gNB->ulsch_decoding_stats);
|
||||
nr_ulsch_decoding(gNB,
|
||||
ULSCH_id,
|
||||
gNB->pusch_vars[ULSCH_id]->llr,
|
||||
frame_parms,
|
||||
pusch_pdu,
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
harq_pid,
|
||||
G);
|
||||
|
||||
if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations){
|
||||
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
|
||||
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
|
||||
}
|
||||
else if(gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->b!=NULL){
|
||||
LOG_D(PHY, "ULSCH received ok \n");
|
||||
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 0);
|
||||
while (gNB->nbDecode > 0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
|
||||
nr_postDecode(gNB, req);
|
||||
delNotifiedFIFO_elt(req);
|
||||
}
|
||||
stop_meas(&gNB->ulsch_decoding_stats);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -111,17 +111,18 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
|
||||
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
|
||||
*/
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t thread_id);
|
||||
|
||||
/*! \brief Scheduling for UE RX procedures in normal subframes.
|
||||
@param last_slot Index of last slot (0-19)
|
||||
@param phy_vars_ue Pointer to UE variables on which to act
|
||||
@param proc Pointer to RXn_TXnp4 proc information
|
||||
@param eNB_id Local id of eNB on which to act
|
||||
@param abstraction_flag Indicator of PHY abstraction
|
||||
@param mode calibration/debug mode
|
||||
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
|
||||
@param phy_vars_rn pointer to RN variables
|
||||
@param ue Pointer to UE variables on which to act
|
||||
@param proc Pointer to proc information
|
||||
@param gNB_id Local id of eNB on which to act
|
||||
@param mode calibration/debug mode
|
||||
*/
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t do_pdcch_flag,runmode_t mode);
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t gNB_id,
|
||||
runmode_t mode);
|
||||
|
||||
int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
|
||||
|
||||
|
||||
|
||||
@@ -57,10 +57,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][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;
|
||||
@@ -93,11 +89,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
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->status = ACTIVE;
|
||||
dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
|
||||
dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
|
||||
dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
|
||||
@@ -121,8 +117,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pdcch_vars->nb_search_space = 0;
|
||||
dl_config->number_pdus = 0;
|
||||
}
|
||||
|
||||
if (scheduled_response->ul_config != NULL){
|
||||
@@ -159,13 +154,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
|
||||
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
|
||||
|
||||
if (scheduled_response->tx_request){
|
||||
if (scheduled_response->tx_request){ // TBR todo here it should loop through the number of tx pdus
|
||||
fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body;
|
||||
|
||||
//harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char));
|
||||
memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
|
||||
|
||||
harq_process_ul_ue->status = ACTIVE;
|
||||
|
||||
scheduled_response->tx_request->number_of_pdus = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -223,7 +219,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
|
||||
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;
|
||||
@@ -233,11 +228,9 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ul_config->number_pdus = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -199,7 +199,7 @@ int main(int argc, char **argv)
|
||||
|
||||
int frame=1,slot=1;
|
||||
int frame_length_complex_samples;
|
||||
int frame_length_complex_samples_no_prefix;
|
||||
//int frame_length_complex_samples_no_prefix;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
UE_nr_rxtx_proc_t UE_proc;
|
||||
NR_Sched_Rsp_t Sched_INFO;
|
||||
@@ -207,12 +207,11 @@ int main(int argc, char **argv)
|
||||
NR_UE_MAC_INST_t *UE_mac;
|
||||
int cyclic_prefix_type = NFAPI_CP_NORMAL;
|
||||
int run_initial_sync=0;
|
||||
int do_pdcch_flag=1;
|
||||
int pusch_tgt_snrx10 = 200;
|
||||
int pucch_tgt_snrx10 = 200;
|
||||
int loglvl=OAILOG_INFO;
|
||||
|
||||
float target_error_rate = 0.01;
|
||||
//float target_error_rate = 0.01;
|
||||
int css_flag=0;
|
||||
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
@@ -374,7 +373,7 @@ int main(int argc, char **argv)
|
||||
|
||||
case 'I':
|
||||
run_initial_sync=1;
|
||||
target_error_rate=0.1;
|
||||
//target_error_rate=0.1;
|
||||
slot = 0;
|
||||
break;
|
||||
|
||||
@@ -600,7 +599,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
|
||||
s_re = malloc(2*sizeof(double*));
|
||||
s_im = malloc(2*sizeof(double*));
|
||||
@@ -713,7 +712,7 @@ int main(int argc, char **argv)
|
||||
|
||||
|
||||
nr_ue_phy_config_request(&UE_mac->phy_config);
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[0]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
|
||||
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
|
||||
snrRun = 0;
|
||||
|
||||
@@ -774,11 +773,11 @@ int main(int argc, char **argv)
|
||||
memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
|
||||
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
|
||||
|
||||
UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
|
||||
|
||||
|
||||
UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
|
||||
UE_list->UE_sched_ctrl[0].current_harq_pid = harq_pid;
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
|
||||
UE_info->UE_sched_ctrl[0].current_harq_pid = harq_pid;
|
||||
gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
|
||||
|
||||
if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config);
|
||||
@@ -898,7 +897,6 @@ int main(int argc, char **argv)
|
||||
phy_procedures_nrUE_RX(UE,
|
||||
&UE_proc,
|
||||
0,
|
||||
do_pdcch_flag,
|
||||
normal_txrx);
|
||||
|
||||
//printf("dlsim round %d ends\n",round);
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "openair1/SIMULATION/RF/rf.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
//#define DEBUG_NR_ULSCHSIM
|
||||
|
||||
@@ -67,6 +68,44 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
|
||||
uint16_t n_rnti = 0x1234;
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
|
||||
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
|
||||
int r = rdata->segment_r;
|
||||
|
||||
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
|
||||
ulsch_harq->processedSegments++;
|
||||
gNB->nbDecode--;
|
||||
|
||||
if (decodeSuccess) {
|
||||
memcpy(ulsch_harq->b+rdata->offset,
|
||||
ulsch_harq->c[r],
|
||||
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
|
||||
} else {
|
||||
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
|
||||
int nb=abortTpool(gNB->threadPool, req->key);
|
||||
nb+=abortNotifiedFIFO(gNB->respDecode, req->key);
|
||||
gNB->nbDecode-=nb;
|
||||
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
|
||||
ulsch_harq->processedSegments, nb, rdata->nbSegments);
|
||||
ulsch_harq->processedSegments=rdata->nbSegments;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if all segments are done
|
||||
if (rdata->nbSegments == ulsch_harq->processedSegments) {
|
||||
if (decodeSuccess) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
ulsch->last_iteration_cnt = rdata->decodeIterations;
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c;
|
||||
@@ -92,7 +131,7 @@ int main(int argc, char **argv)
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
double sigma;
|
||||
unsigned char qbits = 8;
|
||||
int ret;
|
||||
int ret=0;
|
||||
int loglvl = OAILOG_WARNING;
|
||||
uint64_t SSB_positions=0x01;
|
||||
uint16_t nb_symb_sch = 12;
|
||||
@@ -338,6 +377,11 @@ int main(int argc, char **argv)
|
||||
gNB = RC.gNB[0];
|
||||
//gNB_config = &gNB->gNB_config;
|
||||
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
char tp_param[] = "n";
|
||||
initTpool(tp_param, gNB->threadPool, true);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
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;
|
||||
@@ -408,7 +452,7 @@ int main(int argc, char **argv)
|
||||
rel15_ul->pusch_data.rv_index = rvidx;
|
||||
rel15_ul->nrOfLayers = Nl;
|
||||
rel15_ul->target_code_rate = code_rate;
|
||||
rel15_ul->pusch_data.tb_size = TBS>>3;
|
||||
rel15_ul->pusch_data.tb_size = TBS/8;
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
|
||||
@@ -444,7 +488,7 @@ int main(int argc, char **argv)
|
||||
harq_process_ul_ue->pusch_pdu.nr_of_symbols = nb_symb_sch;
|
||||
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.rv_index = rvidx;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS/8;
|
||||
harq_process_ul_ue->a = &test_input[0];
|
||||
|
||||
}
|
||||
@@ -531,10 +575,15 @@ int main(int argc, char **argv)
|
||||
rel15_ul->qam_mod_order,
|
||||
rel15_ul->nrOfLayers);
|
||||
|
||||
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
|
||||
nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
|
||||
frame, subframe, harq_pid, G);
|
||||
while (gNB->nbDecode > 0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
|
||||
ret = nr_postDecode_sim(gNB, req);
|
||||
delNotifiedFIFO_elt(req);
|
||||
}
|
||||
|
||||
if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||
if (ret)
|
||||
n_errors++;
|
||||
|
||||
//count errors
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
//#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"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
|
||||
@@ -201,6 +203,7 @@ int main(int argc, char **argv)
|
||||
int pucch_tgt_snrx10 = 200;
|
||||
int ibwps=24;
|
||||
int ibwp_rboffset=41;
|
||||
int params_from_file = 0;
|
||||
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
|
||||
exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
|
||||
}
|
||||
@@ -437,6 +440,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
params_from_file = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
|
||||
@@ -458,7 +465,7 @@ int main(int argc, char **argv)
|
||||
printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
|
||||
//printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
|
||||
printf("-F Input filename (.txt format) for RX conformance testing\n");
|
||||
printf("-G raw file containing RRC configuration (generated by gNB)\n");
|
||||
printf("-G Offset of samples to read from file (0 default)\n");
|
||||
printf("-M Multiple SSB positions in burst\n");
|
||||
printf("-N Nid_cell\n");
|
||||
printf("-O oversampling factor (1,2,4,8,16)\n");
|
||||
@@ -468,6 +475,7 @@ int main(int argc, char **argv)
|
||||
printf("-P Print ULSCH performances\n");
|
||||
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
|
||||
printf("-Q If -F used, read parameters from file\n");
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
@@ -514,6 +522,11 @@ int main(int argc, char **argv)
|
||||
RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
|
||||
RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
|
||||
gNB = RC.gNB[0];
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
char tp_param[] = "n";
|
||||
initTpool(tp_param, gNB->threadPool, true);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
//gNB_config = &gNB->gNB_config;
|
||||
|
||||
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||
@@ -736,6 +749,7 @@ int main(int argc, char **argv)
|
||||
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
|
||||
snrRun = 0;
|
||||
int n_errs = 0;
|
||||
int read_errors=0;
|
||||
|
||||
int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
|
||||
@@ -745,35 +759,39 @@ int main(int argc, char **argv)
|
||||
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
|
||||
AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
|
||||
|
||||
fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
|
||||
fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
|
||||
printf("rnti %x\n",n_rnti);
|
||||
fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_rb %d\n",nb_rb);
|
||||
int16_t dummy;
|
||||
fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("rb_start %d\n",start_rb);
|
||||
fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_symb_sch %d\n",nb_symb_sch);
|
||||
fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
|
||||
printf("start_symbol %d\n",start_symbol);
|
||||
fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
|
||||
printf("mcs %d\n",Imcs);
|
||||
fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
|
||||
printf("rv_index %d\n",rv_index);
|
||||
// fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
|
||||
fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("harq_pid %d\n",harq_pid);
|
||||
fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
|
||||
sizeof(int16_t),
|
||||
slot_length<<1,
|
||||
input_fd);
|
||||
if (params_from_file) {
|
||||
fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
|
||||
read_errors+=fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
|
||||
printf("rnti %x\n",n_rnti);
|
||||
read_errors+=fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_rb %d\n",nb_rb);
|
||||
int16_t dummy;
|
||||
read_errors+=fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("rb_start %d\n",start_rb);
|
||||
read_errors+=fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_symb_sch %d\n",nb_symb_sch);
|
||||
read_errors+=fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
|
||||
printf("start_symbol %d\n",start_symbol);
|
||||
read_errors+=fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
|
||||
printf("mcs %d\n",Imcs);
|
||||
read_errors+=fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
|
||||
printf("rv_index %d\n",rv_index);
|
||||
// fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
|
||||
read_errors+=fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("harq_pid %d\n",harq_pid);
|
||||
}
|
||||
fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET);
|
||||
read_errors+=fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
|
||||
sizeof(int16_t),
|
||||
slot_length<<1,
|
||||
input_fd);
|
||||
if (read_errors==0) exit(1);
|
||||
for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
|
||||
slot_offset,
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
|
||||
slot_offset,
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
|
||||
}
|
||||
|
||||
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
||||
@@ -784,6 +802,17 @@ int main(int argc, char **argv)
|
||||
int n_errors[4] = {0,0,0,0};;
|
||||
int round_trials[4]={0,0,0,0};
|
||||
uint32_t errors_scrambling[4] = {0,0,0,0};
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
reset_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_unscrambling_stats);
|
||||
reset_meas(&gNB->ulsch_channel_estimation_stats);
|
||||
reset_meas(&gNB->ulsch_llr_stats);
|
||||
reset_meas(&gNB->ulsch_channel_compensation_stats);
|
||||
reset_meas(&gNB->ulsch_rbs_extraction_stats);
|
||||
|
||||
clear_pusch_stats(gNB);
|
||||
for (trial = 0; trial < n_trials; trial++) {
|
||||
@@ -797,19 +826,6 @@ int main(int argc, char **argv)
|
||||
ulsch_ue[0]->harq_processes[harq_pid]->round = round;
|
||||
gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
|
||||
rv_index = nr_rv_round_map[round];
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
reset_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_unscrambling_stats);
|
||||
reset_meas(&gNB->ulsch_channel_estimation_stats);
|
||||
reset_meas(&gNB->ulsch_ptrs_processing_stats);
|
||||
reset_meas(&gNB->ulsch_llr_stats);
|
||||
reset_meas(&gNB->ulsch_mrc_stats);
|
||||
reset_meas(&gNB->ulsch_channel_compensation_stats);
|
||||
reset_meas(&gNB->ulsch_rbs_extraction_stats);
|
||||
|
||||
UE_proc.nr_tti_tx = slot;
|
||||
UE_proc.frame_tx = frame;
|
||||
@@ -901,6 +917,7 @@ int main(int argc, char **argv)
|
||||
ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.qam_mod_order = mod_order;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.rb_size = nb_rb;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.rb_start = start_rb;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.nr_of_symbols = nb_symb_sch;
|
||||
@@ -913,7 +930,7 @@ int main(int argc, char **argv)
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
|
||||
@@ -925,7 +942,7 @@ int main(int argc, char **argv)
|
||||
|
||||
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
|
||||
|
||||
for (int i=0;i<(TBS>>3);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
|
||||
for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
|
||||
double scale = 1;
|
||||
|
||||
if (input_fd == NULL) {
|
||||
@@ -1143,9 +1160,9 @@ int main(int argc, char **argv)
|
||||
printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
|
||||
printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
|
||||
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
|
||||
printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
|
||||
printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
|
||||
printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
|
||||
//printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
|
||||
//printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
|
||||
//printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
|
||||
msi_pos++;
|
||||
while((non_mbsfn_SubframeConfig & (0x100 >> msi_pos)) == (0x100>>msi_pos))
|
||||
msi_pos++;
|
||||
mbms_mch_i=0;
|
||||
mbms_mch_i=0;
|
||||
|
||||
if((subframeP==0)){
|
||||
x=0;
|
||||
|
||||
+49
-54
@@ -27,76 +27,70 @@
|
||||
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include <math.h>
|
||||
#include "PHY/defs_nr_common.h"
|
||||
|
||||
//Table 5.1.2.2-2
|
||||
uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {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,3104,3240,3368,3496,3624,3752,3824};
|
||||
|
||||
uint16_t NPRB_LBRM[7] = {32,66,107,135,162,217,273};
|
||||
|
||||
// Transport block size determination according to 6.1.4.2 of TS 38.214
|
||||
// returns the TBS in bits
|
||||
uint32_t nr_compute_tbs(uint16_t Qm,
|
||||
uint16_t R,
|
||||
uint16_t nb_rb,
|
||||
uint16_t nb_symb_sch,
|
||||
uint16_t nb_dmrs_prb,
|
||||
uint16_t nb_rb,
|
||||
uint16_t nb_symb_sch,
|
||||
uint16_t nb_dmrs_prb,
|
||||
uint16_t nb_rb_oh,
|
||||
uint8_t tb_scaling,
|
||||
uint8_t Nl)
|
||||
uint8_t Nl)
|
||||
{
|
||||
|
||||
uint16_t nbp_re, nb_re;
|
||||
uint32_t nr_tbs=0;
|
||||
uint32_t Ninfo, Np_info, C;
|
||||
uint8_t n, scale;
|
||||
uint16_t nbp_re, nb_re;
|
||||
uint32_t nr_tbs=0;
|
||||
uint32_t Ninfo, Np_info, C;
|
||||
uint8_t n, scale;
|
||||
|
||||
nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
|
||||
nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
|
||||
nb_re = min(156, nbp_re) * nb_rb;
|
||||
scale = (R>1024)?11:10;
|
||||
// Intermediate number of information bits
|
||||
Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling;
|
||||
|
||||
nb_re = min(156, nbp_re) * nb_rb;
|
||||
|
||||
scale = (R>1024)?11:10;
|
||||
|
||||
// Intermediate number of information bits
|
||||
Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling;
|
||||
|
||||
if (Ninfo <=3824) {
|
||||
n = max(3, floor(log2(Ninfo)) - 6);
|
||||
Np_info = max(24, (Ninfo>>n)<<n);
|
||||
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
|
||||
if (Tbstable_nr[i] >= Np_info){
|
||||
nr_tbs = Tbstable_nr[i];
|
||||
break;
|
||||
}
|
||||
if (Ninfo <=3824) {
|
||||
n = max(3, floor(log2(Ninfo)) - 6);
|
||||
Np_info = max(24, (Ninfo>>n)<<n);
|
||||
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
|
||||
if (Tbstable_nr[i] >= Np_info){
|
||||
nr_tbs = Tbstable_nr[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
n = log2(Ninfo-24)-5;
|
||||
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
|
||||
|
||||
if (R <= 256) {
|
||||
C = CEILIDIV((Np_info+24),3816);
|
||||
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
|
||||
} else {
|
||||
if (Np_info > 8424){
|
||||
C = CEILIDIV((Np_info+24),8424);
|
||||
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
|
||||
} else {
|
||||
nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = log2(Ninfo-24)-5;
|
||||
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
|
||||
|
||||
if (R <= 256) {
|
||||
C = CEILIDIV((Np_info+24),3816);
|
||||
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
|
||||
}
|
||||
else {
|
||||
if (Np_info > 8424){
|
||||
C = CEILIDIV((Np_info+24),8424);
|
||||
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
|
||||
}
|
||||
else {
|
||||
nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d, tbs %d\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
|
||||
return nr_tbs;
|
||||
}
|
||||
//printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d, tbs %d\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
|
||||
return nr_tbs;
|
||||
}
|
||||
|
||||
|
||||
//tbslbrm calculation according to 5.4.2.1 of 38.212
|
||||
uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
uint16_t nb_rb,
|
||||
uint8_t Nl,
|
||||
uint8_t C)
|
||||
uint8_t Nl)
|
||||
{
|
||||
|
||||
uint16_t R, nb_re;
|
||||
@@ -104,14 +98,14 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
uint8_t Qm;
|
||||
int i;
|
||||
uint32_t nr_tbs=0;
|
||||
uint32_t Ninfo, Np_info;
|
||||
uint32_t Ninfo, Np_info, C;
|
||||
uint8_t n;
|
||||
|
||||
for (i=0; i<7; i++) {
|
||||
if (NPRB_LBRM[i] >= nb_rb){
|
||||
nb_rb_lbrm = NPRB_LBRM[i];
|
||||
break;
|
||||
}
|
||||
if (NPRB_LBRM[i] >= nb_rb){
|
||||
nb_rb_lbrm = NPRB_LBRM[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Qm = ((table == 1)? 8 : 6);
|
||||
@@ -136,10 +130,12 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
|
||||
|
||||
if (R <= 256) {
|
||||
C = CEILIDIV((Np_info+24),3816);
|
||||
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
|
||||
}
|
||||
else {
|
||||
if (Np_info > 8424){
|
||||
C = CEILIDIV((Np_info+24),8424);
|
||||
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
|
||||
}
|
||||
else {
|
||||
@@ -150,5 +146,4 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
|
||||
}
|
||||
return nr_tbs;
|
||||
|
||||
}
|
||||
@@ -221,6 +221,10 @@ typedef struct {
|
||||
uint32_t RA_tx_frame;
|
||||
/// Random-access variable for window calculation (subframe of last change in window counter)
|
||||
uint8_t RA_tx_subframe;
|
||||
/// Scheduled TX frame for RA Msg3
|
||||
frame_t msg3_frame;
|
||||
/// Scheduled TX slot for RA Msg3
|
||||
slot_t msg3_slot;
|
||||
/// 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)
|
||||
@@ -243,13 +247,11 @@ typedef struct {
|
||||
uint8_t generate_nr_prach;
|
||||
|
||||
//// FAPI-like interface message
|
||||
fapi_nr_tx_request_t tx_request;
|
||||
fapi_nr_ul_config_request_t ul_config_request;
|
||||
fapi_nr_dl_config_request_t dl_config_request;
|
||||
|
||||
/// Interface module instances
|
||||
nr_ue_if_module_t *if_module;
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
nr_phy_config_t phy_config;
|
||||
|
||||
/// BSR report flag management
|
||||
|
||||
@@ -88,6 +88,24 @@ NR_UE_MAC_INST_t *get_mac_inst(
|
||||
\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 fill nr_scheduled_response struct instance
|
||||
@param nr_scheduled_response_t * pointer to scheduled_response instance to fill
|
||||
@param fapi_nr_dl_config_request_t* pointer to dl_config,
|
||||
@param fapi_nr_ul_config_request_t* pointer to ul_config,
|
||||
@param fapi_nr_tx_request_t* pointer to tx_request;
|
||||
@param module_id_t mod_id module ID
|
||||
@param int cc_id CC ID
|
||||
@param frame_t frame frame number
|
||||
@param int slot reference number */
|
||||
void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
fapi_nr_dl_config_request_t *dl_config,
|
||||
fapi_nr_ul_config_request_t *ul_config,
|
||||
fapi_nr_tx_request_t *tx_request,
|
||||
module_id_t mod_id,
|
||||
int cc_id,
|
||||
frame_t frame,
|
||||
int slot);
|
||||
|
||||
/* \brief Get SR payload (0,1) from UE MAC
|
||||
@param Mod_id Instance id of UE in machine
|
||||
@param CC_id Component Carrier index
|
||||
@@ -156,7 +174,7 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index,
|
||||
|
||||
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 nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
int dci_format,
|
||||
uint8_t dci_length,
|
||||
uint16_t rnti,
|
||||
@@ -197,6 +215,17 @@ and fills the PRACH PDU per each FD occasion.
|
||||
*/
|
||||
void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
|
||||
|
||||
/* \brief This function schedules the Msg3 transmission
|
||||
@param
|
||||
@param
|
||||
@param
|
||||
@returns void
|
||||
*/
|
||||
void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac,
|
||||
frame_t current_frame,
|
||||
sub_frame_t current_slot,
|
||||
uint8_t Msg3_tda_id);
|
||||
|
||||
/* \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
|
||||
@@ -212,6 +241,7 @@ random-access procedure
|
||||
uint16_t nr_ue_process_rar(module_id_t mod_id,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
uint8_t * dlsch_buffer,
|
||||
rnti_t * t_crnti,
|
||||
uint8_t preamble_index,
|
||||
@@ -264,5 +294,16 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
|
||||
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
|
||||
|
||||
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);
|
||||
|
||||
int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
|
||||
uint16_t n_RB_ULBWP,
|
||||
uint16_t n_RB_DLBWP,
|
||||
uint16_t riv);
|
||||
|
||||
void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint8_t *nb_dmrs_re_per_rb,
|
||||
uint16_t *number_dmrs_symbols);
|
||||
|
||||
#endif
|
||||
/** @}*/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*! \file nr_l1_helper.c
|
||||
* \brief PHY helper functions for PRACH adapted to NR
|
||||
* \brief PHY/MAC helper functions
|
||||
* \author Guido Casati
|
||||
* \date 2019
|
||||
* \version 2.0
|
||||
@@ -151,3 +151,23 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m
|
||||
|
||||
return receivedTargerPower;
|
||||
}
|
||||
|
||||
void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint8_t *nb_dmrs_re_per_rb,
|
||||
uint16_t *number_dmrs_symbols){
|
||||
|
||||
int start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
uint8_t dmrs_type = pusch_pdu->dmrs_config_type;
|
||||
uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data;
|
||||
|
||||
*number_dmrs_symbols = 0;
|
||||
for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
*number_dmrs_symbols += 1;
|
||||
}
|
||||
|
||||
*nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data;
|
||||
|
||||
}
|
||||
|
||||
@@ -493,9 +493,13 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
|
||||
|
||||
// Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
|
||||
// TbD Msg3 Retransmissions to be scheduled by DCI 0_0
|
||||
mac->RA_active = 0;
|
||||
mac->RA_window_cnt = -1;
|
||||
mac->ra_state = RA_SUCCEEDED;
|
||||
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR successfully received \n", mod_id, frame, nr_tti_tx);
|
||||
mac->generate_nr_prach = 2;
|
||||
LOG_I(MAC, "[MAC][UE %d][RAPROC]: RAR successfully received \n", mod_id);
|
||||
|
||||
} else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
|
||||
|
||||
@@ -578,7 +582,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
||||
|
||||
mac->RA_window_cnt--;
|
||||
|
||||
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception not successful, (RA window count %d) \n",
|
||||
LOG_D(MAC, "[MAC][UE %d][RAPROC][%d.%d]: RAR not received yet (RA window count %d) \n",
|
||||
mod_id,
|
||||
frame,
|
||||
nr_tti_tx,
|
||||
|
||||
@@ -64,11 +64,11 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd
|
||||
|
||||
}
|
||||
|
||||
void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id, uint8_t dci_format){
|
||||
void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id){
|
||||
|
||||
uint16_t monitoringSymbolsWithinSlot;
|
||||
uint16_t monitoringSymbolsWithinSlot = 0;
|
||||
uint8_t bwp_id = 1, coreset_id = 1;
|
||||
int sps;
|
||||
int sps = 0;
|
||||
def_dci_pdu_rel15 = calloc(1,sizeof(dci_pdu_rel15_t));
|
||||
AssertFatal(mac->scc != NULL, "scc is null\n");
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
@@ -76,9 +76,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
|
||||
NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
|
||||
|
||||
// DCI format configuration
|
||||
rel15->dci_format = dci_format;
|
||||
|
||||
// CORESET configuration
|
||||
NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id - 1];
|
||||
rel15->coreset.duration = coreset->duration;
|
||||
@@ -123,7 +120,9 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
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(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_C, rel15->BWPSize, bwp_id);
|
||||
for (int i = 0; i < rel15->num_dci_options; i++) {
|
||||
rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
|
||||
}
|
||||
break;
|
||||
case NR_RNTI_RA:
|
||||
// we use the initial DL BWP
|
||||
@@ -133,7 +132,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
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(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_RA, rel15->BWPSize, bwp_id);
|
||||
rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
|
||||
break;
|
||||
case NR_RNTI_P:
|
||||
break;
|
||||
@@ -177,14 +176,13 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
#endif
|
||||
// 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;
|
||||
dl_config->number_pdus += 1;
|
||||
}
|
||||
|
||||
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) {
|
||||
|
||||
int ss_id;
|
||||
uint8_t bwp_id = 1, coreset_id = 1;
|
||||
NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
|
||||
NR_BWP_Downlink_t *bwp = mac->DLbwp[bwp_id - 1];
|
||||
|
||||
#ifdef DEBUG_DCI
|
||||
@@ -215,7 +213,9 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n");
|
||||
switch(mac->ra_state){
|
||||
case WAIT_RAR:
|
||||
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id, NR_DL_DCI_FORMAT_1_0);
|
||||
rel15->num_dci_options = 1;
|
||||
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
|
||||
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id);
|
||||
fill_dci_search_candidates(ss, rel15);
|
||||
break;
|
||||
case WAIT_CONTENTION_RESOLUTION:
|
||||
@@ -286,7 +286,10 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
// Monitors DCI 01 and 11 scrambled with C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
|
||||
if (get_softmodem_params()->phy_test == 1 && mac->crnti > 0) {
|
||||
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in the user specific search space\n");
|
||||
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id, NR_DL_DCI_FORMAT_1_1);
|
||||
rel15->num_dci_options = 2;
|
||||
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_1;
|
||||
rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_1;
|
||||
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id);
|
||||
fill_dci_search_candidates(ss, rel15);
|
||||
|
||||
#ifdef DEBUG_DCI
|
||||
|
||||
@@ -51,9 +51,10 @@
|
||||
#include "NR_MAC_UE/mac_extern.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
/* PHY UE */
|
||||
/* PHY */
|
||||
#include "SCHED_NR_UE/defs.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
|
||||
/*Openair Packet Tracer */
|
||||
#include "UTIL/OPT/opt.h"
|
||||
@@ -91,6 +92,24 @@ extern void mac_rlc_data_ind (
|
||||
num_tb_t num_tbP,
|
||||
crc_t *crcs_pP);
|
||||
|
||||
void fill_scheduled_response(nr_scheduled_response_t *scheduled_response,
|
||||
fapi_nr_dl_config_request_t *dl_config,
|
||||
fapi_nr_ul_config_request_t *ul_config,
|
||||
fapi_nr_tx_request_t *tx_request,
|
||||
module_id_t mod_id,
|
||||
int cc_id,
|
||||
frame_t frame,
|
||||
int slot){
|
||||
|
||||
scheduled_response->dl_config = dl_config;
|
||||
scheduled_response->ul_config = ul_config;
|
||||
scheduled_response->tx_request = tx_request;
|
||||
scheduled_response->module_id = mod_id;
|
||||
scheduled_response->CC_id = cc_id;
|
||||
scheduled_response->frame = frame;
|
||||
scheduled_response->slot = slot;
|
||||
|
||||
}
|
||||
|
||||
uint32_t get_ssb_slot(uint32_t ssb_index){
|
||||
// this function now only support f <= 3GHz
|
||||
@@ -118,7 +137,7 @@ uint8_t table_9_2_2_1[16][8]={
|
||||
{1,0, 14,26,0,3,0,0}
|
||||
};
|
||||
|
||||
|
||||
#if 0 // Not in use. In case of use, please adapt the schedule_response (no longer in MAC)
|
||||
int8_t nr_ue_process_dlsch(module_id_t module_id,
|
||||
int cc_id,
|
||||
uint8_t gNB_index,
|
||||
@@ -252,6 +271,7 @@ int8_t nr_ue_process_dlsch(module_id_t module_id,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
int cc_id,
|
||||
@@ -719,7 +739,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
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;
|
||||
|
||||
fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
} else { // we have an scg
|
||||
|
||||
@@ -728,17 +751,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
dcireq.cc_id = cc_id;
|
||||
dcireq.frame = rx_frame;
|
||||
dcireq.slot = rx_slot;
|
||||
dcireq.dl_config_req.number_pdus = 0;
|
||||
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;
|
||||
|
||||
fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
@@ -766,7 +782,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
uint8_t data_existing = 0;
|
||||
uint16_t TBS_bytes;
|
||||
uint32_t TBS;
|
||||
int i;
|
||||
int i, N_PRB_oh;
|
||||
|
||||
module_id_t mod_id = ul_info->module_id;
|
||||
uint32_t gNB_index = ul_info->gNB_index;
|
||||
@@ -778,57 +794,101 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
||||
uint8_t access_mode = SCHEDULED_ACCESS;
|
||||
|
||||
// program PUSCH. this should actually be done upon reception of an UL DCI
|
||||
// program PUSCH with UL DCI parameters
|
||||
nr_dcireq_t dcireq;
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
fapi_nr_tx_request_t tx_req;
|
||||
fapi_nr_tx_request_body_t tx_req_body;
|
||||
fapi_nr_ul_config_request_t *ul_config = &dcireq.ul_config_req;
|
||||
nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
|
||||
|
||||
//--------------------------Temporary configuration-----------------------------//
|
||||
uint16_t rnti = 0x1234;
|
||||
uint32_t rb_size = 50;
|
||||
uint32_t rb_start = 0;
|
||||
uint8_t nr_of_symbols = 11;
|
||||
uint8_t start_symbol_index = 0;
|
||||
fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &mac->ul_config_request.ul_config_list[0];
|
||||
|
||||
uint16_t rnti = ulcfg_pdu->pusch_config_pdu.rnti;
|
||||
uint32_t rb_size = ulcfg_pdu->pusch_config_pdu.rb_size;
|
||||
uint32_t rb_start = ulcfg_pdu->pusch_config_pdu.rb_start;
|
||||
uint8_t nr_of_symbols = ulcfg_pdu->pusch_config_pdu.nr_of_symbols;
|
||||
uint8_t start_symbol_index = ulcfg_pdu->pusch_config_pdu.start_symbol_index;
|
||||
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;
|
||||
uint8_t mcs_index = ulcfg_pdu->pusch_config_pdu.mcs_index;
|
||||
uint8_t mcs_table = ulcfg_pdu->pusch_config_pdu.mcs_table;
|
||||
uint8_t harq_process_id = ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id;
|
||||
uint8_t rv_index = ulcfg_pdu->pusch_config_pdu.pusch_data.rv_index;
|
||||
uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
|
||||
uint8_t dmrs_config_type = 0;
|
||||
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
|
||||
// These should come from RRC config!!!
|
||||
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);
|
||||
uint8_t no_data_in_dmrs = 1;
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
uint16_t ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
|
||||
//------------------------------------------------------------------------------//
|
||||
|
||||
for (i = start_symbol_index; i < start_symbol_index + nr_of_symbols; i++) {
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
number_dmrs_symbols += 1;
|
||||
}
|
||||
#ifdef DEBUG_DCI
|
||||
LOG_I(MAC, " UL config params \n rnti: %x \n rb_size: %d \n",
|
||||
rnti, rb_size);
|
||||
LOG_I(MAC, "rb_start: %x \n nr_of_symbols: %d \n start_symbol_index: %d \n nrOfLayers: %d \n mcs_index: %d \n \
|
||||
mcs_table: %d \n harq_process_id: %d \n ndi: %d \n num_cb: %d \n rv_index: %d \n",
|
||||
rb_start, nr_of_symbols, start_symbol_index, nrOfLayers, mcs_index,
|
||||
mcs_table, harq_process_id, ndi, num_cb, rv_index);
|
||||
#endif
|
||||
|
||||
if(no_data_in_dmrs)
|
||||
nb_dmrs_re_per_rb = 12;
|
||||
else
|
||||
nb_dmrs_re_per_rb = ((dmrs_config_type == pusch_dmrs_type1) ? 6:4);
|
||||
// PTRS ports configuration
|
||||
// TbD: ptrs_dmrs_port and ptrs_port_index are not initialised!
|
||||
ptrs_ports_list.ptrs_re_offset = 0;
|
||||
|
||||
TBS = nr_compute_tbs(nr_get_Qm_ul(mcs_index, 0),
|
||||
nr_get_code_rate_ul(mcs_index, 0),
|
||||
rb_size,
|
||||
nr_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
0,
|
||||
0,
|
||||
nrOfLayers);
|
||||
TBS_bytes = TBS/8;
|
||||
// Num PRB Overhead from PUSCH-ServingCellConfig
|
||||
if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL)
|
||||
N_PRB_oh = 0;
|
||||
else
|
||||
N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
|
||||
|
||||
ul_config->slot = ul_info->slot_tx;
|
||||
ul_config->number_pdus = 1;
|
||||
ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = &ptrs_ports_list;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate = nr_get_code_rate_ul(mcs_index, mcs_table);
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order = nr_get_Qm_ul(mcs_index, mcs_table);
|
||||
|
||||
if (1 << ptrs_time_density >= nr_of_symbols) {
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
|
||||
}
|
||||
|
||||
get_num_re_dmrs(&ul_config->ul_config_list[0].pusch_config_pdu,
|
||||
&nb_dmrs_re_per_rb,
|
||||
&number_dmrs_symbols);
|
||||
|
||||
TBS = nr_compute_tbs(ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order,
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate,
|
||||
rb_size,
|
||||
nr_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
N_PRB_oh,
|
||||
0,
|
||||
nrOfLayers);
|
||||
TBS_bytes = TBS/8;
|
||||
ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS_bytes;
|
||||
|
||||
if (IS_SOFTMODEM_NOS1){
|
||||
// Getting IP traffic to be transmitted
|
||||
@@ -876,8 +936,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
dcireq.frame = rx_frame;
|
||||
dcireq.slot = rx_slot;
|
||||
|
||||
scheduled_response.dl_config = NULL;
|
||||
scheduled_response.ul_config = &dcireq.ul_config_req;
|
||||
// Config UL TX PDU
|
||||
tx_req.slot = slot_tx;
|
||||
tx_req.sfn = frame_tx;
|
||||
@@ -886,41 +944,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
tx_req_body.pdu_length = TBS_bytes;
|
||||
tx_req_body.pdu_index = 0;
|
||||
tx_req_body.pdu = ulsch_input_buffer;
|
||||
tx_req.tx_request_body = &tx_req_body;
|
||||
|
||||
scheduled_response.tx_request = &tx_req;
|
||||
scheduled_response.tx_request->tx_request_body = &tx_req_body;
|
||||
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 = ul_dmrs_symb_pos;
|
||||
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.num_dmrs_cdm_grps_no_data = 1;
|
||||
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
|
||||
}
|
||||
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
@@ -929,11 +955,116 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
// 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 if (get_softmodem_params()->do_ra){
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id);
|
||||
|
||||
if (mac->RA_active && ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){
|
||||
|
||||
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
fapi_nr_tx_request_t tx_req;
|
||||
fapi_nr_tx_request_body_t tx_req_body;
|
||||
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
|
||||
fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus];
|
||||
uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size;
|
||||
|
||||
//if (IS_SOFTMODEM_NOS1){
|
||||
// // Getting IP traffic to be transmitted
|
||||
// data_existing = nr_ue_get_sdu(mod_id,
|
||||
// cc_id,
|
||||
// frame_tx,
|
||||
// slot_tx,
|
||||
// 0,
|
||||
// ulsch_input_buffer,
|
||||
// TBS_bytes,
|
||||
// &access_mode);
|
||||
//}
|
||||
|
||||
//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
|
||||
LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes);
|
||||
//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)
|
||||
ulsch_input_buffer[0] = 0x31;
|
||||
for (int i = 1; i < TBS_bytes; i++) {
|
||||
ulsch_input_buffer[i] = (unsigned char) rand();
|
||||
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
|
||||
}
|
||||
//}
|
||||
|
||||
LOG_D(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n",
|
||||
ul_info->module_id,
|
||||
ul_info->frame_tx,
|
||||
ul_info->slot_tx,
|
||||
mac->t_crnti);
|
||||
|
||||
// Config UL TX PDU
|
||||
tx_req.slot = ul_info->slot_tx;
|
||||
tx_req.sfn = ul_info->frame_tx;
|
||||
tx_req.number_of_pdus = 1;
|
||||
tx_req_body.pdu_length = TBS_bytes;
|
||||
tx_req_body.pdu_index = 0;
|
||||
tx_req_body.pdu = ulsch_input_buffer;
|
||||
tx_req.tx_request_body = &tx_req_body;
|
||||
ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
|
||||
ul_config->number_pdus++;
|
||||
// scheduled_response
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return UE_CONNECTION_OK;
|
||||
}
|
||||
|
||||
// PUSCH Msg3 scheduled by RAR UL grant according to 8.3 of TS 38.213
|
||||
// Note: Msg3 tx in the uplink symbols of mixed slot
|
||||
void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac,
|
||||
frame_t current_frame,
|
||||
sub_frame_t current_slot,
|
||||
uint8_t Msg3_tda_id){
|
||||
|
||||
int delta = 0;
|
||||
NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
|
||||
int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
struct NR_PUSCH_TimeDomainResourceAllocationList *pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
// k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1
|
||||
// PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon
|
||||
uint8_t k2 = *pusch_TimeDomainAllocationList->list.array[Msg3_tda_id]->k2;
|
||||
|
||||
switch (mu) {
|
||||
case 0:
|
||||
delta = 2;
|
||||
break;
|
||||
case 1:
|
||||
delta = 3;
|
||||
break;
|
||||
case 2:
|
||||
delta = 4;
|
||||
break;
|
||||
case 3:
|
||||
delta = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
mac->msg3_slot = (current_slot + k2 + delta) % nr_slots_per_frame[mu];
|
||||
if (current_slot + k2 + delta > nr_slots_per_frame[mu])
|
||||
mac->msg3_frame = (current_frame + 1) % 1024;
|
||||
else
|
||||
mac->msg3_frame = current_frame;
|
||||
|
||||
#ifdef DEBUG_MSG3
|
||||
LOG_D(MAC, "[DEBUG_MSG3] current_slot %d k2 %d delta %d temp_slot %d mac->msg3_frame %d mac->msg3_slot %d \n", current_slot, k2, delta, current_slot + k2 + delta, mac->msg3_frame, mac->msg3_slot);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -951,6 +1082,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
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_scheduled_response_t scheduled_response;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
||||
@@ -1081,10 +1213,11 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mac->ra_state == RA_SUCCEEDED){
|
||||
mac->generate_nr_prach = 2;
|
||||
}
|
||||
mac->scheduled_response.ul_config = ul_config;
|
||||
|
||||
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP);
|
||||
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
|
||||
mac->if_module->scheduled_response(&scheduled_response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2261,13 +2394,22 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
|
||||
*/
|
||||
if(pusch_config_pdu != NULL){
|
||||
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
|
||||
if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config)
|
||||
if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
|
||||
pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
|
||||
|
||||
}
|
||||
else if (mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
|
||||
pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
}
|
||||
|
||||
if (pusch_TimeDomainAllocationList) {
|
||||
AssertFatal(pusch_TimeDomainAllocationList->list.count > time_domain_ind,
|
||||
"time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n",
|
||||
time_domain_ind,pusch_TimeDomainAllocationList->list.count);
|
||||
if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) {
|
||||
LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
|
||||
time_domain_ind, pusch_TimeDomainAllocationList->list.count);
|
||||
pusch_config_pdu->start_symbol_index=0;
|
||||
pusch_config_pdu->nr_of_symbols=0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength;
|
||||
int S,L;
|
||||
SLIV2SL(startSymbolAndLength,&S,&L);
|
||||
@@ -2295,8 +2437,8 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
|
||||
LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
|
||||
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,def_dci_pdu_rel15);
|
||||
return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci->dci_format));
|
||||
int dci_format = nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15);
|
||||
return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci_format));
|
||||
}
|
||||
|
||||
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
|
||||
@@ -2317,6 +2459,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
|
||||
LOG_D(MAC,"nr_ue_process_dci at MAC layer with dci_format=%d (DL BWP %d, UL BWP %d)\n",dci_format,n_RB_DLBWP,n_RB_ULBWP);
|
||||
|
||||
NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
|
||||
NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
|
||||
switch(dci_format){
|
||||
case NR_UL_DCI_FORMAT_0_0:
|
||||
@@ -2423,6 +2566,23 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
|
||||
pusch_config_pdu_0_1->frequency_hopping = dci->frequency_hopping_flag.val;
|
||||
/* MCS */
|
||||
pusch_config_pdu_0_1->mcs_index = dci->mcs;
|
||||
/* MCS TABLE */
|
||||
if (pusch_config->transformPrecoder == NULL) {
|
||||
if (mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
|
||||
pusch_config_pdu_0_1->transform_precoding = 1;
|
||||
else
|
||||
pusch_config_pdu_0_1->transform_precoding = 0;
|
||||
}
|
||||
else
|
||||
pusch_config_pdu_0_1->transform_precoding = *pusch_config->transformPrecoder;
|
||||
|
||||
if (pusch_config_pdu_0_1->transform_precoding == transform_precoder_disabled)
|
||||
pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_Table, 0,
|
||||
dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false);
|
||||
else
|
||||
pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_TableTransformPrecoder, 1,
|
||||
dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false);
|
||||
|
||||
/* NDI */
|
||||
pusch_config_pdu_0_1->pusch_data.new_data_indicator = dci->ndi;
|
||||
/* RV */
|
||||
@@ -3100,7 +3260,33 @@ void nr_ue_send_sdu(module_id_t module_idP,
|
||||
|
||||
}
|
||||
|
||||
void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
// N_RB configuration according to 7.3.1.0 (DCI size alignment) of TS 38.212
|
||||
int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){
|
||||
|
||||
int N_RB = 0, start_RB;
|
||||
switch(rnti_type) {
|
||||
case NR_RNTI_RA:
|
||||
case NR_RNTI_TC:
|
||||
case NR_RNTI_P:
|
||||
case NR_RNTI_SI:
|
||||
if (mac->DLbwp[0]->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero) {
|
||||
uint8_t bwp_id = 1;
|
||||
uint8_t coreset_id = 0; // assuming controlResourceSetId is 0 for controlResourceSetZero
|
||||
NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id];
|
||||
get_coreset_rballoc(coreset->frequencyDomainResources.buf,&N_RB,&start_RB);
|
||||
} else {
|
||||
N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
|
||||
}
|
||||
break;
|
||||
case NR_RNTI_C:
|
||||
N_RB = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
break;
|
||||
}
|
||||
return N_RB;
|
||||
|
||||
}
|
||||
|
||||
int nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
int dci_format,
|
||||
uint8_t dci_size,
|
||||
uint16_t rnti,
|
||||
@@ -3117,21 +3303,45 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
AssertFatal(rnti_type!=-1,"no identified/handled rnti\n");
|
||||
AssertFatal(mac->DLbwp[0] != NULL, "DLbwp[0] shouldn't be null here!\n");
|
||||
AssertFatal(mac->ULbwp[0] != NULL, "ULbwp[0] shouldn't be null here!\n");
|
||||
int N_RB = (mac->scg != NULL) ?
|
||||
NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) :
|
||||
NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275);
|
||||
int N_RB = get_n_rb(mac, rnti_type);
|
||||
int N_RB_UL = (mac->scg != NULL) ?
|
||||
NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) :
|
||||
NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275);
|
||||
|
||||
int pos=0;
|
||||
int fsize=0;
|
||||
|
||||
if (rnti_type == NR_RNTI_C) {
|
||||
// First find out the DCI format from the first bit (UE performed blind decoding)
|
||||
pos++;
|
||||
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
|
||||
#ifdef DEBUG_EXTRACT_DCI
|
||||
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
|
||||
#endif
|
||||
|
||||
if (dci_format == NR_UL_DCI_FORMAT_0_0 || dci_format == NR_DL_DCI_FORMAT_1_0) {
|
||||
if (dci_pdu_rel15->format_indicator == 0)
|
||||
dci_format = NR_UL_DCI_FORMAT_0_0;
|
||||
else
|
||||
dci_format = NR_DL_DCI_FORMAT_1_0;
|
||||
}
|
||||
else if (dci_format == NR_UL_DCI_FORMAT_0_1 || dci_format == NR_DL_DCI_FORMAT_1_1) {
|
||||
// In case the sizes of formats 0_1 and 1_1 happen to be the same
|
||||
if (dci_pdu_rel15->format_indicator == 0)
|
||||
dci_format = NR_UL_DCI_FORMAT_0_1;
|
||||
else
|
||||
dci_format = NR_DL_DCI_FORMAT_1_1;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_EXTRACT_DCI
|
||||
LOG_D(MAC, "DCI format is %d\n", dci_format);
|
||||
#endif
|
||||
|
||||
switch(dci_format) {
|
||||
|
||||
case NR_DL_DCI_FORMAT_1_0:
|
||||
switch(rnti_type) {
|
||||
case NR_RNTI_RA:
|
||||
N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); // TBR hotfix
|
||||
// Freq domain assignment
|
||||
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
pos=fsize;
|
||||
@@ -3168,13 +3378,6 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
case NR_RNTI_C:
|
||||
|
||||
// indicating a DL DCI format 1bit
|
||||
pos++;
|
||||
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
|
||||
#ifdef DEBUG_EXTRACT_DCI
|
||||
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
|
||||
#endif
|
||||
|
||||
// Freq domain assignment (275rb >> fsize = 16)
|
||||
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
pos+=fsize;
|
||||
@@ -3375,18 +3578,16 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
switch(rnti_type)
|
||||
{
|
||||
case NR_RNTI_C:
|
||||
// indicating a DL DCI format 1bit
|
||||
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
|
||||
// Freq domain assignment max 16 bit
|
||||
fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
|
||||
pos+=fsize;
|
||||
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
|
||||
// Time domain assignment 4bit
|
||||
pos+=4;
|
||||
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
|
||||
// Frequency hopping flag – 1 bit
|
||||
pos++;
|
||||
dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
|
||||
// This is not supported yet - Skip for now
|
||||
// Frequency hopping flag – 1 bit
|
||||
//pos++;
|
||||
//dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
|
||||
// MCS 5 bit
|
||||
pos+=5;
|
||||
dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
|
||||
@@ -3450,89 +3651,203 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
break;
|
||||
|
||||
case NR_DL_DCI_FORMAT_1_1:
|
||||
// Format indicator
|
||||
pos=1;
|
||||
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
|
||||
// Carrier indicator
|
||||
pos+=dci_pdu_rel15->carrier_indicator.nbits;
|
||||
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
|
||||
// BWP Indicator
|
||||
pos+=dci_pdu_rel15->bwp_indicator.nbits;
|
||||
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
|
||||
// Frequency domain resource assignment
|
||||
pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
|
||||
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1);
|
||||
// Time domain resource assignment
|
||||
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
|
||||
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1);
|
||||
// VRB-to-PRB mapping
|
||||
pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits;
|
||||
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1);
|
||||
// PRB bundling size indicator
|
||||
pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits;
|
||||
dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1);
|
||||
// Rate matching indicator
|
||||
pos+=dci_pdu_rel15->rate_matching_indicator.nbits;
|
||||
dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1);
|
||||
// ZP CSI-RS trigger
|
||||
pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits;
|
||||
dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1);
|
||||
//TB1
|
||||
// MCS 5bit
|
||||
pos+=5;
|
||||
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
|
||||
// New data indicator 1bit
|
||||
pos+=1;
|
||||
dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1;
|
||||
// Redundancy version 2bit
|
||||
pos+=2;
|
||||
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3;
|
||||
//TB2
|
||||
// MCS 5bit
|
||||
pos+=dci_pdu_rel15->mcs2.nbits;
|
||||
dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1);
|
||||
// New data indicator 1bit
|
||||
pos+=dci_pdu_rel15->ndi2.nbits;
|
||||
dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1);
|
||||
// Redundancy version 2bit
|
||||
pos+=dci_pdu_rel15->rv2.nbits;
|
||||
dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1);
|
||||
// HARQ process number 4bit
|
||||
pos+=4;
|
||||
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
|
||||
// Downlink assignment index
|
||||
pos+=dci_pdu_rel15->dai[0].nbits;
|
||||
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
|
||||
// TPC command for scheduled PUCCH 2bit
|
||||
pos+=2;
|
||||
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3;
|
||||
// PUCCH resource indicator 3bit
|
||||
pos+=3;
|
||||
dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3;
|
||||
// PDSCH-to-HARQ_feedback timing indicator
|
||||
pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits;
|
||||
dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1);
|
||||
// Antenna ports
|
||||
pos+=dci_pdu_rel15->antenna_ports.nbits;
|
||||
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
|
||||
// TCI
|
||||
pos+=dci_pdu_rel15->transmission_configuration_indication.nbits;
|
||||
dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1);
|
||||
// SRS request
|
||||
pos+=dci_pdu_rel15->srs_request.nbits;
|
||||
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
|
||||
// CBG transmission information
|
||||
pos+=dci_pdu_rel15->cbgti.nbits;
|
||||
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
|
||||
// CBG flushing out information
|
||||
pos+=dci_pdu_rel15->cbgfi.nbits;
|
||||
dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1);
|
||||
// DMRS sequence init
|
||||
pos+=1;
|
||||
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1;
|
||||
break;
|
||||
switch(rnti_type)
|
||||
{
|
||||
case NR_RNTI_C:
|
||||
// Carrier indicator
|
||||
pos+=dci_pdu_rel15->carrier_indicator.nbits;
|
||||
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
|
||||
// BWP Indicator
|
||||
pos+=dci_pdu_rel15->bwp_indicator.nbits;
|
||||
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
|
||||
// Frequency domain resource assignment
|
||||
pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
|
||||
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1);
|
||||
// Time domain resource assignment
|
||||
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
|
||||
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1);
|
||||
// VRB-to-PRB mapping
|
||||
pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits;
|
||||
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1);
|
||||
// PRB bundling size indicator
|
||||
pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits;
|
||||
dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1);
|
||||
// Rate matching indicator
|
||||
pos+=dci_pdu_rel15->rate_matching_indicator.nbits;
|
||||
dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1);
|
||||
// ZP CSI-RS trigger
|
||||
pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits;
|
||||
dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1);
|
||||
//TB1
|
||||
// MCS 5bit
|
||||
pos+=5;
|
||||
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
|
||||
// New data indicator 1bit
|
||||
pos+=1;
|
||||
dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1;
|
||||
// Redundancy version 2bit
|
||||
pos+=2;
|
||||
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3;
|
||||
//TB2
|
||||
// MCS 5bit
|
||||
pos+=dci_pdu_rel15->mcs2.nbits;
|
||||
dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1);
|
||||
// New data indicator 1bit
|
||||
pos+=dci_pdu_rel15->ndi2.nbits;
|
||||
dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1);
|
||||
// Redundancy version 2bit
|
||||
pos+=dci_pdu_rel15->rv2.nbits;
|
||||
dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1);
|
||||
// HARQ process number 4bit
|
||||
pos+=4;
|
||||
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
|
||||
// Downlink assignment index
|
||||
pos+=dci_pdu_rel15->dai[0].nbits;
|
||||
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
|
||||
// TPC command for scheduled PUCCH 2bit
|
||||
pos+=2;
|
||||
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3;
|
||||
// PUCCH resource indicator 3bit
|
||||
pos+=3;
|
||||
dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3;
|
||||
// PDSCH-to-HARQ_feedback timing indicator
|
||||
pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits;
|
||||
dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1);
|
||||
// Antenna ports
|
||||
pos+=dci_pdu_rel15->antenna_ports.nbits;
|
||||
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
|
||||
// TCI
|
||||
pos+=dci_pdu_rel15->transmission_configuration_indication.nbits;
|
||||
dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1);
|
||||
// SRS request
|
||||
pos+=dci_pdu_rel15->srs_request.nbits;
|
||||
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
|
||||
// CBG transmission information
|
||||
pos+=dci_pdu_rel15->cbgti.nbits;
|
||||
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
|
||||
// CBG flushing out information
|
||||
pos+=dci_pdu_rel15->cbgfi.nbits;
|
||||
dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1);
|
||||
// DMRS sequence init
|
||||
pos+=1;
|
||||
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case NR_UL_DCI_FORMAT_0_1:
|
||||
switch(rnti_type)
|
||||
{
|
||||
case NR_RNTI_C:
|
||||
// Carrier indicator
|
||||
pos+=dci_pdu_rel15->carrier_indicator.nbits;
|
||||
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
|
||||
|
||||
// UL/SUL Indicator
|
||||
pos+=dci_pdu_rel15->ul_sul_indicator.nbits;
|
||||
dci_pdu_rel15->ul_sul_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ul_sul_indicator.nbits)-1);
|
||||
|
||||
// BWP Indicator
|
||||
pos+=dci_pdu_rel15->bwp_indicator.nbits;
|
||||
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
|
||||
|
||||
// Freq domain assignment max 16 bit
|
||||
fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
|
||||
//pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
|
||||
pos+=fsize;
|
||||
|
||||
//pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
|
||||
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
|
||||
|
||||
// Time domain assignment 4bit
|
||||
//pos+=4;
|
||||
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
|
||||
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0x3;
|
||||
|
||||
// Not supported yet - skip for now
|
||||
// Frequency hopping flag – 1 bit
|
||||
//pos++;
|
||||
//dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
|
||||
|
||||
// MCS 5 bit
|
||||
pos+=5;
|
||||
dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
|
||||
|
||||
// New data indicator 1bit
|
||||
pos++;
|
||||
dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1;
|
||||
|
||||
// Redundancy version 2bit
|
||||
pos+=2;
|
||||
dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3;
|
||||
|
||||
// HARQ process number 4bit
|
||||
pos+=4;
|
||||
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
|
||||
|
||||
// 1st Downlink assignment index
|
||||
pos+=dci_pdu_rel15->dai[0].nbits;
|
||||
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
|
||||
|
||||
// 2nd Downlink assignment index
|
||||
pos+=dci_pdu_rel15->dai[1].nbits;
|
||||
dci_pdu_rel15->dai[1].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[1].nbits)-1);
|
||||
|
||||
// TPC command for scheduled PUSCH – 2 bits
|
||||
pos+=2;
|
||||
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3;
|
||||
|
||||
// SRS resource indicator
|
||||
pos+=dci_pdu_rel15->srs_resource_indicator.nbits;
|
||||
dci_pdu_rel15->srs_resource_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_resource_indicator.nbits)-1);
|
||||
|
||||
// Precoding info and n. of layers
|
||||
pos+=dci_pdu_rel15->precoding_information.nbits;
|
||||
dci_pdu_rel15->precoding_information.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->precoding_information.nbits)-1);
|
||||
|
||||
// Antenna ports
|
||||
pos+=dci_pdu_rel15->antenna_ports.nbits;
|
||||
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
|
||||
|
||||
// SRS request
|
||||
pos+=dci_pdu_rel15->srs_request.nbits;
|
||||
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
|
||||
|
||||
// CSI request
|
||||
pos+=dci_pdu_rel15->csi_request.nbits;
|
||||
dci_pdu_rel15->csi_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->csi_request.nbits)-1);
|
||||
|
||||
// CBG transmission information
|
||||
pos+=dci_pdu_rel15->cbgti.nbits;
|
||||
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
|
||||
|
||||
// PTRS DMRS association
|
||||
pos+=dci_pdu_rel15->ptrs_dmrs_association.nbits;
|
||||
dci_pdu_rel15->ptrs_dmrs_association.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ptrs_dmrs_association.nbits)-1);
|
||||
|
||||
// Beta offset indicator
|
||||
pos+=dci_pdu_rel15->beta_offset_indicator.nbits;
|
||||
dci_pdu_rel15->beta_offset_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->beta_offset_indicator.nbits)-1);
|
||||
|
||||
// DMRS sequence initialization
|
||||
pos+=dci_pdu_rel15->dmrs_sequence_initialization.nbits;
|
||||
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dmrs_sequence_initialization.nbits)-1);
|
||||
|
||||
// UL-SCH indicator
|
||||
pos+=1;
|
||||
dci_pdu_rel15->ulsch_indicator = (*dci_pdu>>(dci_size-pos))&0x1;
|
||||
|
||||
// UL/SUL indicator – 1 bit
|
||||
/* commented for now (RK): need to get this from BWP descriptor
|
||||
if (cfg->pucch_config.pucch_GroupHopping.value)
|
||||
dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ul_sul_indicator&1)<<(dci_size-pos++);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return dci_format;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include <common/utils/nr/nr_common.h>
|
||||
|
||||
#define DEBUG_RAR
|
||||
// #define DEBUG_RAR
|
||||
// #define DEBUG_MSG3
|
||||
|
||||
// table 7.2-1 TS 38.321
|
||||
uint16_t table_7_2_1[16] = {
|
||||
@@ -66,6 +67,135 @@ uint16_t table_7_2_1[16] = {
|
||||
1920, // row index 13
|
||||
};
|
||||
|
||||
void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac,
|
||||
int Msg3_f_alloc,
|
||||
uint8_t Msg3_t_alloc,
|
||||
uint8_t mcs,
|
||||
uint8_t freq_hopping){
|
||||
|
||||
int f_alloc, mask, StartSymbolIndex, NrOfSymbols;
|
||||
uint8_t nb_dmrs_re_per_rb;
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
int N_PRB_oh;
|
||||
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu;
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
|
||||
NR_BWP_UplinkDedicated_t *ibwp = mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP;
|
||||
NR_PUSCH_Config_t *pusch_Config = ibwp->pusch_Config->choice.setup;
|
||||
int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[Msg3_t_alloc]->startSymbolAndLength;
|
||||
|
||||
#ifdef DEBUG_MSG3
|
||||
printf("[DEBUG_MSG3] Configuring 1 Msg3 PDU of %d UL pdus \n", ul_config->number_pdus);
|
||||
#endif
|
||||
|
||||
// Num PRB Overhead from PUSCH-ServingCellConfig
|
||||
if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL)
|
||||
N_PRB_oh = 0;
|
||||
else
|
||||
N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead;
|
||||
|
||||
// active BWP start
|
||||
int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
|
||||
// initial BWP start
|
||||
int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275);
|
||||
int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275);
|
||||
|
||||
// BWP start selection according to 8.3 of TS 38.213
|
||||
pusch_config_pdu->bwp_size = ibwp_size;
|
||||
if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
|
||||
pusch_config_pdu->bwp_start = abwp_start;
|
||||
else
|
||||
pusch_config_pdu->bwp_start = ibwp_start;
|
||||
|
||||
//// Resource assignment from RAR
|
||||
// Frequency domain allocation according to 8.3 of TS 38.213
|
||||
if (ibwp_size < 180)
|
||||
mask = (1 << ((int) ceil(log2((ibwp_size*(ibwp_size+1))>>1)))) - 1;
|
||||
else
|
||||
mask = (1 << (28 - (int)(ceil(log2((ibwp_size*(ibwp_size+1))>>1))))) - 1;
|
||||
f_alloc = Msg3_f_alloc & mask;
|
||||
nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc);
|
||||
|
||||
// virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211)
|
||||
pusch_config_pdu->rb_start += ibwp_start - abwp_start;
|
||||
|
||||
// Time domain allocation
|
||||
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
|
||||
pusch_config_pdu->ul_dmrs_symb_pos = 1<<StartSymbolIndex;
|
||||
pusch_config_pdu->start_symbol_index = StartSymbolIndex;
|
||||
pusch_config_pdu->nr_of_symbols = NrOfSymbols;
|
||||
|
||||
#ifdef DEBUG_MSG3
|
||||
printf("[DEBUG_MSG3] Freq assignment (RB start %d size %d) BWP (start %d, size %d), Time assignment (sliv_S %d sliv_L %d) \n",
|
||||
pusch_config_pdu->rb_start,
|
||||
pusch_config_pdu->rb_size,
|
||||
pusch_config_pdu->bwp_start,
|
||||
pusch_config_pdu->bwp_size,
|
||||
StartSymbolIndex,
|
||||
NrOfSymbols);
|
||||
#endif
|
||||
|
||||
// MCS
|
||||
pusch_config_pdu->mcs_index = mcs;
|
||||
// Frequency hopping
|
||||
pusch_config_pdu->frequency_hopping = freq_hopping;
|
||||
// TC-RNTI
|
||||
pusch_config_pdu->rnti = mac->t_crnti;
|
||||
|
||||
// DM-RS configuration according to 6.2.2 UE DM-RS transmission procedure in 38.214
|
||||
pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1;
|
||||
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2;
|
||||
pusch_config_pdu->dmrs_ports = 1;
|
||||
get_num_re_dmrs(pusch_config_pdu,
|
||||
&nb_dmrs_re_per_rb,
|
||||
&number_dmrs_symbols);
|
||||
|
||||
// DMRS sequence initialization [TS 38.211, sec 6.4.1.1.1].
|
||||
// Should match what is sent in DCI 0_1, otherwise set to 0.
|
||||
pusch_config_pdu->scid = 0;
|
||||
|
||||
// Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
|
||||
pusch_config_pdu->transform_precoding = 1;
|
||||
else
|
||||
pusch_config_pdu->transform_precoding = 0;
|
||||
|
||||
// Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214
|
||||
pusch_config_pdu->resource_alloc = pusch_Config->resourceAllocation;
|
||||
|
||||
//// Completing PUSCH PDU
|
||||
pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
|
||||
pusch_config_pdu->mcs_table = 0;
|
||||
pusch_config_pdu->nrOfLayers = 1;
|
||||
pusch_config_pdu->cyclic_prefix = 0;
|
||||
pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
|
||||
pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
|
||||
pusch_config_pdu->data_scrambling_id = *scc->physCellId;
|
||||
pusch_config_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
|
||||
pusch_config_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
pusch_config_pdu->vrb_to_prb_mapping = 0;
|
||||
pusch_config_pdu->uplink_frequency_shift_7p5khz = 0;
|
||||
//Optional Data only included if indicated in pduBitmap
|
||||
pusch_config_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213
|
||||
pusch_config_pdu->pusch_data.harq_process_id = 0;
|
||||
pusch_config_pdu->pusch_data.new_data_indicator = 1; // new data
|
||||
pusch_config_pdu->pusch_data.num_cb = 0;
|
||||
|
||||
// Compute TBS
|
||||
pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order,
|
||||
pusch_config_pdu->target_code_rate,
|
||||
pusch_config_pdu->rb_size,
|
||||
pusch_config_pdu->nr_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
N_PRB_oh,
|
||||
0, // TBR to verify tb scaling
|
||||
pusch_config_pdu->nrOfLayers)/8;
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
// Random Access Response PDU //
|
||||
// TS 38.213 ch 8.2 //
|
||||
@@ -90,12 +220,13 @@ uint16_t table_7_2_1[16] = {
|
||||
//| F_alloc |Time allocation|//
|
||||
//| MCS | TPC |CSI|//
|
||||
/////////////////////////////////////
|
||||
// WIP todo:
|
||||
// TbD WIP Msg3 development ongoing
|
||||
// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213
|
||||
// - apply tpc command, csi req, mcs
|
||||
// - apply tpc command
|
||||
uint16_t nr_ue_process_rar(module_id_t mod_id,
|
||||
int CC_id,
|
||||
frame_t frameP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
uint8_t * dlsch_buffer,
|
||||
rnti_t * t_crnti,
|
||||
uint8_t preamble_index,
|
||||
@@ -106,11 +237,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
|
||||
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; // WIP
|
||||
//uint16_t ta_command = 0, msg3_f_alloc, bwp_size; // WIP
|
||||
uint16_t ta_command = 0;
|
||||
//int f_alloc, mask; // WIP
|
||||
|
||||
AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n");
|
||||
|
||||
@@ -126,7 +253,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
|
||||
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);
|
||||
LOG_I(PHY, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
|
||||
rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
|
||||
ue_mac->RA_RAPID_found = 1;
|
||||
break;
|
||||
@@ -139,17 +266,19 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
|
||||
}
|
||||
};
|
||||
|
||||
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_subheaders, n_subPDUs);
|
||||
#ifdef DEBUG_RAR
|
||||
LOG_D(MAC, "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n", frame, slot, n_subheaders, n_subPDUs);
|
||||
LOG_D(MAC, "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
|
||||
#endif
|
||||
|
||||
// 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 0 // TbD WIP Msg3 development ongoing
|
||||
if (ue_mac->RA_RAPID_found) {
|
||||
|
||||
uint8_t freq_hopping, mcs, Msg3_t_alloc, Msg3_f_alloc;
|
||||
unsigned char tpc_command, csi_req;
|
||||
|
||||
// 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
|
||||
@@ -182,27 +311,36 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
|
||||
ue_mac->Msg3_TPC = 8;
|
||||
break;
|
||||
}
|
||||
//MCS
|
||||
// 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
|
||||
// time alloc
|
||||
Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07);
|
||||
// frequency alloc
|
||||
Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
|
||||
// frequency hopping
|
||||
freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
|
||||
|
||||
#ifdef DEBUG_RAR
|
||||
LOG_D(MAC, "[DEBUG_RAR] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n",
|
||||
Msg3_t_alloc,
|
||||
Msg3_f_alloc,
|
||||
ta_command,
|
||||
mcs,
|
||||
freq_hopping,
|
||||
tpc_command,
|
||||
csi_req,
|
||||
ue_mac->t_crnti);
|
||||
#endif
|
||||
|
||||
// Config Msg3 PDU
|
||||
nr_config_Msg3_pdu(ue_mac, Msg3_f_alloc, Msg3_t_alloc, mcs, freq_hopping);
|
||||
// Schedule Msg3
|
||||
nr_ue_msg3_scheduler(ue_mac, frame, slot, Msg3_t_alloc);
|
||||
|
||||
} else {
|
||||
ue_mac->t_crnti = 0;
|
||||
ta_command = (0xffff);
|
||||
}
|
||||
#endif
|
||||
|
||||
// move the selected RAR to the front of the RA_PDSCH buffer
|
||||
memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1);
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
#include "NR_MIB.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
|
||||
/* Softmodem params */
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
//extern int l2_init_gNB(void);
|
||||
extern void mac_top_init_gNB(void);
|
||||
@@ -346,22 +349,34 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
|
||||
if (secondaryCellGroup) {
|
||||
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
|
||||
int UE_id;
|
||||
if (add_ue == 1) {
|
||||
UE_id = add_new_nr_ue(Mod_idP,rnti);
|
||||
UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup;
|
||||
uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count;
|
||||
UE_list->preambles[UE_id].num_preambles = num_preamble;
|
||||
UE_list->preambles[UE_id].preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
|
||||
for (int i=0; i<num_preamble; i++) {
|
||||
UE_list->preambles[UE_id].preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
|
||||
}
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
if (add_ue == 1 && get_softmodem_params()->phy_test) {
|
||||
const int UE_id = add_new_nr_ue(Mod_idP,rnti);
|
||||
UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
|
||||
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
|
||||
AssertFatal(bwpList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
bwpList->list.count);
|
||||
const int bwp_id = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
|
||||
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
|
||||
}
|
||||
else { // secondaryCellGroup has been updated
|
||||
UE_id = find_nr_UE_id(Mod_idP,rnti);
|
||||
UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup;
|
||||
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
|
||||
/* TODO: should check for free RA process */
|
||||
const int CC_id = 0;
|
||||
NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0];
|
||||
ra->state = RA_IDLE;
|
||||
ra->secondaryCellGroup = secondaryCellGroup;
|
||||
ra->crnti = rnti;
|
||||
uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count;
|
||||
ra->preambles.num_preambles = num_preamble;
|
||||
ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
|
||||
for (int i = 0; i < num_preamble; i++)
|
||||
ra->preambles.preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
|
||||
LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
|
||||
} else { // secondaryCellGroup has been updated
|
||||
const int UE_id = find_nr_UE_id(Mod_idP,rnti);
|
||||
UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
|
||||
LOG_I(PHY,"Modified UE_id %d/%x with secondaryCellGroup\n",UE_id,rnti);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,19 +63,19 @@ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
|
||||
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
|
||||
|
||||
void clear_mac_stats(gNB_MAC_INST *gNB) {
|
||||
memset((void*)gNB->UE_list.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
|
||||
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
|
||||
}
|
||||
|
||||
void dump_mac_stats(gNB_MAC_INST *gNB) {
|
||||
|
||||
NR_UE_list_t *UE_list = &gNB->UE_list;
|
||||
NR_UE_info_t *UE_info = &gNB->UE_info;
|
||||
NR_mac_stats_t *stats;
|
||||
int lc_id;
|
||||
|
||||
for (int UE_id=0;UE_id<MAX_MOBILES_PER_GNB;UE_id++) {
|
||||
if (UE_list->active[UE_id] == TRUE) {
|
||||
LOG_I(MAC,"UE %x\n",UE_list->rnti[UE_id]);
|
||||
stats = &UE_list->mac_stats[UE_id];
|
||||
if (UE_info->active[UE_id]) {
|
||||
LOG_I(MAC, "UE %x\n", UE_info->rnti[UE_id]);
|
||||
stats = &UE_info->mac_stats[UE_id];
|
||||
LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors);
|
||||
LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes);
|
||||
LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors);
|
||||
@@ -130,18 +130,18 @@ void check_nr_ul_failure(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP) {
|
||||
|
||||
UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||
nfapi_nr_dl_dci_request_t *DL_req = &RC.nrmac[module_idP]->DL_req[0];
|
||||
uint16_t rnti = UE_RNTI(module_idP, UE_id);
|
||||
NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
|
||||
|
||||
// check uplink failure
|
||||
if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
|
||||
(UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
|
||||
if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
|
||||
(UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
|
||||
LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
|
||||
if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
|
||||
UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
|
||||
if (UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
|
||||
UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
|
||||
|
||||
// add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
|
||||
nfapi_nr_dl_dci_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_tti_request_body.dl_config_pdu_list[DL_req[CC_id].dl_tti_request_body.number_pdu];
|
||||
@@ -151,7 +151,7 @@ void check_nr_ul_failure(module_id_t module_idP,
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_DCI_REQUEST_DCI_DL_PDU_REL8_TAG;
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A;
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id),
|
||||
UE_list->UE_sched_ctrl[UE_id].
|
||||
UE_info->UE_sched_ctrl[UE_id].
|
||||
dl_cqi[CC_id], format1A);
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
|
||||
@@ -167,27 +167,27 @@ void check_nr_ul_failure(module_id_t module_idP,
|
||||
LOG_I(MAC,
|
||||
"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
|
||||
UE_id, rnti,
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer,
|
||||
dl_config_pdu->dci_dl_pdu.
|
||||
dci_dl_pdu_rel8.resource_block_coding);
|
||||
} else { // ra_pdcch_sent==1
|
||||
LOG_I(MAC,
|
||||
"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",
|
||||
UE_id, rnti,
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
|
||||
if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
|
||||
if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames
|
||||
}
|
||||
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer++;
|
||||
// check threshold
|
||||
if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
|
||||
if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
|
||||
// inform RRC of failure and clear timer
|
||||
LOG_I(MAC,
|
||||
"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
|
||||
UE_id, rnti);
|
||||
mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti);
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
|
||||
|
||||
//Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
|
||||
if (rrc_agent_registered[module_idP]) {
|
||||
@@ -204,7 +204,7 @@ void check_nr_ul_failure(module_id_t module_idP,
|
||||
void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
|
||||
{
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
UE_list_t *UE_list = &gNB->UE_list;
|
||||
NR_UE_info_t *UE_info = &gNB->UE_info;
|
||||
nfapi_ul_config_request_body_t *ul_req;
|
||||
int CC_id, UE_id;
|
||||
NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
|
||||
@@ -238,16 +238,16 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
|
||||
if ((1 << tmp) & deltaTSFC) {
|
||||
// This is an SRS subframe, loop over UEs
|
||||
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
|
||||
if (!RC.nrmac[module_idP]->UE_list.active[UE_id]) continue;
|
||||
if (!RC.nrmac[module_idP]->UE_info.active[UE_id]) continue;
|
||||
ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body;
|
||||
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
|
||||
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue;
|
||||
|
||||
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
|
||||
AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
|
||||
"physicalConfigDedicated is null for UE %d\n",
|
||||
UE_id);
|
||||
|
||||
if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
|
||||
if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
|
||||
if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
|
||||
get_srs_pos(&cc[CC_id],
|
||||
soundingRS_UL_ConfigDedicated->choice.
|
||||
@@ -262,7 +262,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
|
||||
ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu));
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_info->UE_template[CC_id][UE_id].rnti;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
|
||||
@@ -275,7 +275,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
|
||||
ul_req->number_of_pdus++;
|
||||
} // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
|
||||
} // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
|
||||
} // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
|
||||
} // if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
|
||||
} // for (UE_id ...
|
||||
} // if((1<<tmp) & deltaTSFC)
|
||||
|
||||
@@ -322,9 +322,9 @@ void nr_schedule_pusch(int Mod_idP,
|
||||
sub_frame_t slotP) {
|
||||
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
int k = slotP + ul_slots - num_slots_per_tdd;
|
||||
NR_sched_pusch *pusch = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k];
|
||||
NR_sched_pusch *pusch = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k];
|
||||
if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) {
|
||||
UL_tti_req->SFN = pusch->frame;
|
||||
UL_tti_req->Slot = pusch->slot;
|
||||
@@ -332,7 +332,7 @@ void nr_schedule_pusch(int Mod_idP,
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu;
|
||||
UL_tti_req->n_pdus+=1;
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
0, sizeof(NR_sched_pusch));
|
||||
}
|
||||
}
|
||||
@@ -348,10 +348,10 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
uint16_t O_ack;
|
||||
uint8_t SR_flag = 0; // no SR in PUCCH implemented for now
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
|
||||
AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id);
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
int bwp_id=1;
|
||||
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
|
||||
@@ -359,7 +359,7 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
NR_sched_pucch *curr_pucch;
|
||||
|
||||
for (int k=0; k<nr_ulmix_slots; k++) {
|
||||
curr_pucch = &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k];
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k];
|
||||
if ((curr_pucch->dai_c > 0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
|
||||
UL_tti_req->SFN = curr_pucch->frame;
|
||||
UL_tti_req->Slot = curr_pucch->ul_slot;
|
||||
@@ -381,60 +381,48 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
O_ack,
|
||||
SR_flag);
|
||||
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){
|
||||
|
||||
if((bitmap>>slot)&0x01)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
return (bitmap >> slot) & 0x01;
|
||||
}
|
||||
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot){
|
||||
|
||||
|
||||
protocol_ctxt_t ctxt;
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
|
||||
|
||||
int CC_id;
|
||||
int UE_id;
|
||||
uint64_t *dlsch_in_slot_bitmap=NULL;
|
||||
uint64_t *ulsch_in_slot_bitmap=NULL;
|
||||
int pucch_sched;
|
||||
|
||||
UE_id=0;
|
||||
int bwp_id = 1;
|
||||
const int UE_id = 0;
|
||||
const int bwp_id = 1;
|
||||
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_UE_list_t *UE_list = &gNB->UE_list;
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
NR_UE_info_t *UE_info = &gNB->UE_info;
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_COMMON_channels_t *cc = gNB->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])>>(7-scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
||||
|
||||
int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
|
||||
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0)
|
||||
nr_ulmix_slots++;
|
||||
NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||
const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
|
||||
const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
|
||||
|
||||
if (slot== 0 && (UE_list->UEcontext[UE_id].fiveG_connected || get_softmodem_params()->phy_test)) {
|
||||
|
||||
if (slot == 0 && UE_info->active[UE_id]) {
|
||||
|
||||
for (int k=0; k<nr_ulmix_slots; k++) {
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
/* Seems to be covered 384? */
|
||||
/*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
sizeof(NR_sched_pucch));*/
|
||||
/* Seems to be covered in line 335? */
|
||||
/*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pusch));
|
||||
sizeof(NR_sched_pusch));*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,9 +430,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
|
||||
|
||||
pdcp_run(&ctxt);
|
||||
|
||||
nr_rrc_rx_tx(); //&ctxt, CC_id);
|
||||
/* send tick to RLC every ms */
|
||||
/* send tick to RLC and RRC every ms */
|
||||
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
|
||||
void nr_rlc_tick(int frame, int subframe);
|
||||
@@ -452,57 +437,21 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||
}
|
||||
|
||||
dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch
|
||||
ulsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch
|
||||
|
||||
// hardcoding dlsch to be in slot 1
|
||||
if (!(slot%num_slots_per_tdd)) {
|
||||
if(slot==0) {
|
||||
*dlsch_in_slot_bitmap = 0x02;
|
||||
*ulsch_in_slot_bitmap = 0x100;
|
||||
}
|
||||
else {
|
||||
*dlsch_in_slot_bitmap = 0x00;
|
||||
*ulsch_in_slot_bitmap = 0x00;
|
||||
}
|
||||
}
|
||||
const uint64_t dlsch_in_slot_bitmap = (1 << 1);
|
||||
const uint64_t ulsch_in_slot_bitmap = (1 << 8);
|
||||
|
||||
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
|
||||
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
//mbsfn_status[CC_id] = 0;
|
||||
|
||||
// clear vrb_maps
|
||||
memset(cc[CC_id].vrb_map, 0, 100);
|
||||
memset(cc[CC_id].vrb_map_UL, 0, 100);
|
||||
memset(cc[CC_id].vrb_map, 0, 275);
|
||||
memset(cc[CC_id].vrb_map_UL, 0, 275);
|
||||
|
||||
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
|
||||
}
|
||||
|
||||
// refresh UE list based on UEs dropped by PHY in previous subframe
|
||||
/*
|
||||
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_list->active[i]) {
|
||||
|
||||
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++)
|
||||
*/
|
||||
|
||||
|
||||
// This schedules MIB
|
||||
if((slot == 0) && (frame & 7) == 0){
|
||||
schedule_nr_mib(module_idP, frame, slot);
|
||||
}
|
||||
|
||||
if (get_softmodem_params()->phy_test == 0)
|
||||
nr_schedule_RA(module_idP, frame, slot);
|
||||
else
|
||||
UE_list->UEcontext[UE_id].fiveG_connected = true;
|
||||
|
||||
if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]);
|
||||
|
||||
@@ -527,10 +476,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
nr_schedule_RA(module_idP, frame, slot);
|
||||
nr_schedule_reception_msg3(module_idP, 0, frame, slot);
|
||||
} else
|
||||
UE_list->UEcontext[UE_id].fiveG_connected = true;
|
||||
|
||||
if (UE_list->UEcontext[UE_id].fiveG_connected ) {
|
||||
}
|
||||
|
||||
if (UE_info->active[UE_id]) {
|
||||
// TbD once RACH is available, start ta_timer when UE is connected
|
||||
if (ue_sched_ctl->ta_timer)
|
||||
ue_sched_ctl->ta_timer--;
|
||||
@@ -543,29 +492,34 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
}
|
||||
|
||||
// This schedules the DCI for Uplink and subsequently PUSCH
|
||||
if (UE_list->UEcontext[UE_id].fiveG_connected) {
|
||||
|
||||
// The decision about whether to schedule is done for each UE independently
|
||||
// inside
|
||||
if (UE_info->active[UE_id] && slot < 10) {
|
||||
|
||||
int tda = 1; // time domain assignment hardcoded for now
|
||||
schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda);
|
||||
schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap);
|
||||
nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot);
|
||||
}
|
||||
|
||||
if (UE_list->UEcontext[UE_id].fiveG_connected && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot%num_slots_per_tdd))) {
|
||||
|
||||
if (UE_info->active[UE_id]
|
||||
&& (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd))
|
||||
&& (!get_softmodem_params()->phy_test || slot == 1)
|
||||
&& slot < 10) {
|
||||
|
||||
ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
|
||||
nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched);
|
||||
nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
|
||||
//int pucch_sched;
|
||||
//nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched);
|
||||
//nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_info->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
|
||||
nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd);
|
||||
ue_sched_ctl->ta_apply = false;
|
||||
}
|
||||
|
||||
|
||||
if (UE_list->UEcontext[UE_id].fiveG_connected )
|
||||
if (UE_info->active[UE_id])
|
||||
nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot);
|
||||
|
||||
/*
|
||||
// Allocate CCEs for good after scheduling is done
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
|
||||
allocate_CCEs(module_idP, CC_id, subframeP, 0);
|
||||
*/
|
||||
|
||||
stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
|
||||
|
||||
@@ -247,14 +247,11 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
|
||||
uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL
|
||||
NR_SearchSpace_t *ss;
|
||||
int UE_id = 0;
|
||||
// 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[UE_id];
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
NR_RA_t *ra = &cc->ra[0];
|
||||
@@ -262,23 +259,23 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
// if the preamble received correspond to one of the listed
|
||||
// the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
|
||||
int pr_found=0;
|
||||
for (int i=0;i<UE_list->preambles[UE_id].num_preambles;i++) {
|
||||
if (preamble_index == UE_list->preambles[UE_id].preamble_list[i]) {
|
||||
for (int i = 0; i < ra->preambles.num_preambles; i++) {
|
||||
if (preamble_index == ra->preambles.preamble_list[i]) {
|
||||
pr_found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pr_found)
|
||||
UE_list->UEcontext[UE_id].fiveG_connected = false;
|
||||
else {
|
||||
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated for UE_id %d\n",
|
||||
module_idP, preamble_index, UE_id);
|
||||
|
||||
if (!pr_found) {
|
||||
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
|
||||
module_idP, preamble_index);
|
||||
|
||||
return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
|
||||
}
|
||||
|
||||
// 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];
|
||||
NR_BWP_Downlink_t *bwp=ra->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);
|
||||
|
||||
@@ -325,7 +322,6 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
|
||||
ra->RA_rnti = ra_rnti;
|
||||
ra->preamble_index = preamble_index;
|
||||
UE_list->tc_rnti[UE_id] = ra->rnti;
|
||||
|
||||
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,
|
||||
@@ -423,7 +419,6 @@ void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frame
|
||||
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;
|
||||
ra->state = RA_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -434,8 +429,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
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;
|
||||
|
||||
if (ra->state == RA_IDLE) {
|
||||
LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
|
||||
@@ -447,13 +440,12 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
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];
|
||||
AssertFatal(ra->secondaryCellGroup,
|
||||
"no secondaryCellGroup for RNTI %04x\n",
|
||||
ra->crnti);
|
||||
AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
|
||||
NR_BWP_Uplink_t *ubwp = ra->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,
|
||||
@@ -542,17 +534,15 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP){
|
||||
|
||||
int UE_id = 0, dci_formats[2], rnti_types[2], mcsIndex;
|
||||
int dci_formats[2], rnti_types[2], mcsIndex;
|
||||
int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 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;
|
||||
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
|
||||
@@ -597,11 +587,13 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
// 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];
|
||||
AssertFatal(ra->secondaryCellGroup,
|
||||
"no secondaryCellGroup for RNTI %04x\n",
|
||||
ra->crnti);
|
||||
AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
|
||||
NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
|
||||
NR_BWP_Uplink_t *ubwp=ra->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);
|
||||
|
||||
@@ -681,7 +673,30 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
dci_pdu_rel15[0].mcs,
|
||||
dci_pdu_rel15[0].tb_scaling);
|
||||
|
||||
nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, RA_rnti, 0, ss, scc, bwp);
|
||||
uint8_t nr_of_candidates, aggregation_level;
|
||||
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */);
|
||||
int CCEIndex = allocate_nr_CCEs(
|
||||
nr_mac,
|
||||
bwp,
|
||||
coreset,
|
||||
aggregation_level,
|
||||
0, /* n_RNTI 0: common search space */
|
||||
0); // m
|
||||
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
|
||||
return;
|
||||
}
|
||||
nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
RA_rnti,
|
||||
ss,
|
||||
coreset,
|
||||
scc,
|
||||
bwp,
|
||||
aggregation_level,
|
||||
CCEIndex);
|
||||
|
||||
LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti);
|
||||
|
||||
@@ -696,7 +711,7 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
pdcch_pdu_rel15->StartSymbolIndex,
|
||||
pdcch_pdu_rel15->DurationSymbols);
|
||||
|
||||
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id);
|
||||
fill_dci_pdu_rel15(scc,ra->secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id);
|
||||
|
||||
dl_req->nPDUs+=2;
|
||||
|
||||
@@ -719,6 +734,11 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
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);
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
uint8_t *vrb_map = cc[CC_id].vrb_map;
|
||||
for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++)
|
||||
vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
|
||||
|
||||
if (mib_sdu_length > 0) {
|
||||
|
||||
LOG_I(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length);
|
||||
LOG_D(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length);
|
||||
|
||||
if ((frameP & 1023) < 80){
|
||||
LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length);
|
||||
@@ -137,6 +137,11 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
|
||||
dl_req->nPDUs++;
|
||||
|
||||
uint8_t *vrb_map = cc[CC_id].vrb_map;
|
||||
const int rbStart = dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA;
|
||||
for (int rb = 0; rb < 20; rb++)
|
||||
vrb_map[rbStart + rb] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
/*PHY*/
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
/*MAC*/
|
||||
#include "NR_MAC_COMMON/nr_mac.h"
|
||||
@@ -45,6 +46,9 @@
|
||||
/*TAG*/
|
||||
#include "NR_TAG-Id.h"
|
||||
|
||||
/*Softmodem params*/
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
/////* DLSCH MAC PDU generation (6.1.2 TS 38.321) */////
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -54,6 +58,7 @@
|
||||
//#define SIZE_OF_POINTER sizeof (void *)
|
||||
|
||||
int nr_generate_dlsch_pdu(module_id_t module_idP,
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl,
|
||||
unsigned char *sdus_payload,
|
||||
unsigned char *mac_pdu,
|
||||
unsigned char num_sdus,
|
||||
@@ -70,14 +75,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
|
||||
// MAC CEs
|
||||
uint8_t mac_header_control_elements[16], *ce_ptr;
|
||||
ce_ptr = &mac_header_control_elements[0];
|
||||
uint16_t UE_id = 0; //TODO need to get as a function parameter or need to invoke api to UE_id using module Id and RNTI
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
|
||||
NR_UE_list_t *UE_list = &gNB_mac->UE_list;
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = NULL;
|
||||
//NR_CellGroupConfig_t *config = UE_list->secondaryCellGroup[UE_id];
|
||||
ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]);
|
||||
|
||||
NR_mac_stats_t *mac_stats = &(UE_list->mac_stats[UE_id]);
|
||||
|
||||
// 1) Compute MAC CE and related subheaders
|
||||
|
||||
@@ -329,8 +326,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
|
||||
memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]);
|
||||
dlsch_buffer_ptr += sdu_lengths[i];
|
||||
mac_pdu_ptr += sdu_lengths[i];
|
||||
|
||||
mac_stats->lc_bytes_tx[sdu_lcids[i]] += sdu_lengths[i];
|
||||
}
|
||||
|
||||
// 4) Compute final offset for padding
|
||||
@@ -412,6 +407,409 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_
|
||||
UL_info->uci_ind.num_ucis = 0;
|
||||
}
|
||||
|
||||
/* functionalities of this function have been moved to nr_schedule_uss_dlsch_phytest */
|
||||
void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) {
|
||||
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
AssertFatal(tda < tdaList->list.count,
|
||||
"time_domain_allocation %d>=%d\n",
|
||||
tda,
|
||||
tdaList->list.count);
|
||||
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
return nrOfSymbols;
|
||||
}
|
||||
|
||||
nfapi_nr_dmrs_type_e getDmrsConfigType(NR_BWP_Downlink_t *bwp) {
|
||||
return bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
|
||||
}
|
||||
|
||||
uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) {
|
||||
const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(bwp);
|
||||
if (dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
|
||||
// if no data in dmrs cdm group is 1 only even REs have no data
|
||||
// if no data in dmrs cdm group is 2 both odd and even REs have no data
|
||||
return numDmrsCdmGrpsNoData * 6;
|
||||
} else {
|
||||
return numDmrsCdmGrpsNoData * 4;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
|
||||
AssertFatal(UE_info->num_UEs <= 1,
|
||||
"%s() cannot handle more than one UE, but found %d\n",
|
||||
__func__,
|
||||
UE_info->num_UEs);
|
||||
if (UE_info->num_UEs == 0)
|
||||
return;
|
||||
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
sched_ctrl->rbSize = 0;
|
||||
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
const int lcid = DL_SCH_LCID_DTCH;
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||
rnti,
|
||||
module_id,
|
||||
frame,
|
||||
slot,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
0,
|
||||
0);
|
||||
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
|
||||
if (sched_ctrl->num_total_bytes == 0 && !get_softmodem_params()->phy_test)
|
||||
return;
|
||||
LOG_D(MAC,
|
||||
"%d.%d, DTCH%d->DLSCH, RLC status %d bytes\n",
|
||||
frame,
|
||||
slot,
|
||||
lcid,
|
||||
sched_ctrl->rlc_status[lcid].bytes_in_buffer);
|
||||
|
||||
/* Find a free CCE */
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space);
|
||||
sched_ctrl->coreset = get_coreset(
|
||||
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
UE_info->rnti[UE_id],
|
||||
0); // m
|
||||
if (sched_ctrl->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): could not find CCE for UE %d\n", __func__, UE_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find PUCCH occasion */
|
||||
nr_update_pucch_scheduling(
|
||||
module_id, UE_id, frame, slot, num_slots_per_tdd, &sched_ctrl->pucch_sched_idx);
|
||||
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
|
||||
|
||||
uint8_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
|
||||
if (harq->round != 0) { /* retransmission */
|
||||
sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation;
|
||||
|
||||
/* ensure that there is a free place for RB allocation */
|
||||
int rbSize = 0;
|
||||
while (rbSize < retInfo->rbSize) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++;
|
||||
if (rbStart >= bwpSize) {
|
||||
LOG_E(MAC,
|
||||
"cannot allocate retransmission for UE %d/RNTI %04x: no resources\n",
|
||||
UE_id,
|
||||
rnti);
|
||||
return;
|
||||
}
|
||||
while (rbStart + rbSize < bwpSize
|
||||
&& !vrb_map[rbStart + rbSize]
|
||||
&& rbSize < retInfo->rbSize)
|
||||
rbSize++;
|
||||
}
|
||||
sched_ctrl->rbSize = retInfo->rbSize;
|
||||
sched_ctrl->rbStart = rbStart;
|
||||
|
||||
/* MCS etc: just reuse from previous scheduling opportunity */
|
||||
sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx;
|
||||
sched_ctrl->mcs = retInfo->mcs;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData;
|
||||
} else {
|
||||
// Time-domain allocation
|
||||
sched_ctrl->time_domain_allocation = 2;
|
||||
|
||||
// modulation scheme
|
||||
sched_ctrl->mcsTableIdx = 0;
|
||||
sched_ctrl->mcs = 9;
|
||||
sched_ctrl->numDmrsCdmGrpsNoData = 1;
|
||||
|
||||
// Freq-demain allocation
|
||||
while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++;
|
||||
|
||||
uint8_t N_PRB_DMRS =
|
||||
getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
|
||||
int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
|
||||
sched_ctrl->time_domain_allocation);
|
||||
|
||||
int rbSize = 0;
|
||||
uint32_t TBS = 0;
|
||||
do {
|
||||
rbSize++;
|
||||
TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
rbSize,
|
||||
nrOfSymbols,
|
||||
N_PRB_DMRS, // FIXME // This should be multiplied by the
|
||||
// number of dmrs symbols
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
} while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes);
|
||||
sched_ctrl->rbSize = rbSize;
|
||||
sched_ctrl->rbStart = rbStart;
|
||||
}
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
|
||||
vrb_map[rb + sched_ctrl->rbStart] = 1;
|
||||
}
|
||||
|
||||
void nr_schedule_ue_spec(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd) {
|
||||
/* PREPROCESSOR */
|
||||
nr_simple_dlsch_preprocessor(module_id, frame, slot, num_slots_per_tdd);
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||
|
||||
const int CC_id = 0;
|
||||
|
||||
NR_UE_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
if (sched_ctrl->rbSize <= 0 && !get_softmodem_params()->phy_test)
|
||||
continue;
|
||||
|
||||
const rnti_t rnti = UE_info->rnti[UE_id];
|
||||
|
||||
/* POST processing */
|
||||
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
AssertFatal(sched_ctrl->time_domain_allocation < tdaList->list.count,
|
||||
"time_domain_allocation %d>=%d\n",
|
||||
sched_ctrl->time_domain_allocation,
|
||||
tdaList->list.count);
|
||||
|
||||
const int startSymbolAndLength =
|
||||
tdaList->list.array[sched_ctrl->time_domain_allocation]->startSymbolAndLength;
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
uint8_t N_PRB_DMRS =
|
||||
getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
|
||||
const uint32_t TBS =
|
||||
nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
sched_ctrl->rbSize,
|
||||
nrOfSymbols,
|
||||
N_PRB_DMRS, // FIXME // This should be multiplied by the
|
||||
// number of dmrs symbols
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx];
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
harq->is_waiting = 1;
|
||||
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nr_fill_nfapi_dl_pdu(module_id,
|
||||
UE_id,
|
||||
sched_ctrl->active_bwp->bwp_Id,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
dl_req,
|
||||
pucch,
|
||||
1 /* nrOfLayers */,
|
||||
sched_ctrl->mcs,
|
||||
sched_ctrl->rbSize,
|
||||
sched_ctrl->rbStart,
|
||||
sched_ctrl->numDmrsCdmGrpsNoData,
|
||||
getDmrsConfigType(sched_ctrl->active_bwp),
|
||||
sched_ctrl->mcsTableIdx,
|
||||
nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
|
||||
TBS,
|
||||
sched_ctrl->time_domain_allocation,
|
||||
startSymbolIndex,
|
||||
nrOfSymbols,
|
||||
sched_ctrl->aggregation_level,
|
||||
sched_ctrl->cce_index,
|
||||
current_harq_pid,
|
||||
harq->ndi,
|
||||
harq->round);
|
||||
|
||||
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
|
||||
if (harq->round != 0) { /* retransmission */
|
||||
if (sched_ctrl->rbSize != retInfo->rbSize)
|
||||
LOG_W(MAC,
|
||||
"retransmission uses different rbSize (%d vs. orig %d)\n",
|
||||
sched_ctrl->rbSize,
|
||||
retInfo->rbSize);
|
||||
if (sched_ctrl->time_domain_allocation != retInfo->time_domain_allocation)
|
||||
LOG_W(MAC,
|
||||
"retransmission uses different time_domain_allocation (%d vs. orig %d)\n",
|
||||
sched_ctrl->time_domain_allocation,
|
||||
retInfo->time_domain_allocation);
|
||||
if (sched_ctrl->mcs != retInfo->mcs
|
||||
|| sched_ctrl->mcsTableIdx != retInfo->mcsTableIdx
|
||||
|| sched_ctrl->numDmrsCdmGrpsNoData != retInfo->numDmrsCdmGrpsNoData)
|
||||
LOG_W(MAC,
|
||||
"retransmission uses different table/MCS/numDmrsCdmGrpsNoData (%d/%d/%d vs. orig %d/%d/%d)\n",
|
||||
sched_ctrl->mcsTableIdx,
|
||||
sched_ctrl->mcs,
|
||||
sched_ctrl->numDmrsCdmGrpsNoData,
|
||||
retInfo->mcsTableIdx,
|
||||
retInfo->mcs,
|
||||
retInfo->numDmrsCdmGrpsNoData);
|
||||
/* we do not have to do anything, since we do not require to get data
|
||||
* from RLC, encode MAC CEs, or copy data to FAPI structures */
|
||||
LOG_W(MAC, "%d.%2d retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
|
||||
} else { /* initial transmission */
|
||||
|
||||
/* reserve space for timing advance of UE if necessary,
|
||||
* nr_generate_dlsch_pdu() checks for ta_apply and add TA CE if necessary */
|
||||
const int ta_len = (sched_ctrl->ta_apply) ? 2 : 0;
|
||||
|
||||
/* Get RLC data TODO: remove random data retrieval */
|
||||
int header_length_total = 0;
|
||||
int header_length_last = 0;
|
||||
int sdu_length_total = 0;
|
||||
int num_sdus = 0;
|
||||
uint16_t sdu_lengths[NB_RB_MAX] = {0};
|
||||
uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
|
||||
unsigned char sdu_lcids[NB_RB_MAX] = {0};
|
||||
const int lcid = DL_SCH_LCID_DTCH;
|
||||
if (sched_ctrl->num_total_bytes > 0) {
|
||||
LOG_D(MAC,
|
||||
"[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting "
|
||||
"%d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n",
|
||||
module_id,
|
||||
frame,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3,
|
||||
lcid,
|
||||
header_length_total,
|
||||
TBS);
|
||||
|
||||
sdu_lengths[num_sdus] = mac_rlc_data_req(module_id,
|
||||
rnti,
|
||||
module_id,
|
||||
frame,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
TBS - ta_len - header_length_total - sdu_length_total - 3,
|
||||
(char *)&mac_sdus[sdu_length_total],
|
||||
0,
|
||||
0);
|
||||
|
||||
LOG_D(MAC,
|
||||
"[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
|
||||
module_id,
|
||||
sdu_lengths[num_sdus],
|
||||
lcid);
|
||||
|
||||
sdu_lcids[num_sdus] = lcid;
|
||||
sdu_length_total += sdu_lengths[num_sdus];
|
||||
header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
|
||||
header_length_total += header_length_last;
|
||||
|
||||
num_sdus++;
|
||||
|
||||
//ue_sched_ctl->uplane_inactivity_timer = 0;
|
||||
}
|
||||
else if (get_softmodem_params()->phy_test) {
|
||||
LOG_D(MAC, "Configuring DL_TX in %d.%d: random data\n", frame, slot);
|
||||
// fill dlsch_buffer with random data
|
||||
for (int i = 0; i < TBS; i++)
|
||||
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
|
||||
sdu_lcids[0] = 0x3f; // DRB
|
||||
sdu_lengths[0] = TBS - ta_len - 3;
|
||||
header_length_total += 2 + (sdu_lengths[0] >= 128);
|
||||
sdu_length_total += sdu_lengths[0];
|
||||
num_sdus +=1;
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total;
|
||||
|
||||
// Check if there is data from RLC or CE
|
||||
const int post_padding = TBS >= 2 + header_length_total + sdu_length_total + ta_len;
|
||||
// padding param currently not in use
|
||||
//padding = TBS - header_length_total - sdu_length_total - ta_len - 1;
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
/* pointer to directly generate the PDU into the nFAPI structure */
|
||||
uint32_t *buf = tx_req->TLVs[0].value.direct;
|
||||
|
||||
const int offset = nr_generate_dlsch_pdu(
|
||||
module_id,
|
||||
sched_ctrl,
|
||||
(unsigned char *)mac_sdus,
|
||||
(unsigned char *)buf,
|
||||
num_sdus, // num_sdus
|
||||
sdu_lengths,
|
||||
sdu_lcids,
|
||||
255, // no drx
|
||||
NULL, // contention res id
|
||||
post_padding);
|
||||
|
||||
// Padding: fill remainder of DLSCH with 0
|
||||
if (post_padding > 0) {
|
||||
for (int j = 0; j < TBS - offset; j++)
|
||||
buf[offset + j] = 0;
|
||||
}
|
||||
|
||||
/* the buffer has been filled by nr_generate_dlsch_pdu(), below we simply
|
||||
* fill the remaining information */
|
||||
tx_req->PDU_length = TBS;
|
||||
tx_req->PDU_index = gNB_mac->pdu_index[0]++;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
gNB_mac->TX_req[CC_id].SFN = frame;
|
||||
gNB_mac->TX_req[CC_id].Slot = slot;
|
||||
|
||||
retInfo->rbSize = sched_ctrl->rbSize;
|
||||
retInfo->time_domain_allocation = sched_ctrl->time_domain_allocation;
|
||||
retInfo->mcsTableIdx = sched_ctrl->mcsTableIdx;
|
||||
retInfo->mcs = sched_ctrl->mcs;
|
||||
retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
if (frame%100 == 0) {
|
||||
LOG_I(MAC,
|
||||
"%d.%d, first 10 payload bytes, TBS size: %d \n",
|
||||
frame,
|
||||
slot,
|
||||
TBS);
|
||||
for(int i = 0; i < 10; i++)
|
||||
LOG_I(MAC, "byte %d: %x\n", i, ((uint8_t *) buf)[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,14 +252,12 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int configure_fapi_dl_pdu(int Mod_idP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
uint8_t *mcsIndex,
|
||||
uint16_t *rbSize,
|
||||
uint16_t *rbStart) {
|
||||
|
||||
int configure_fapi_dl_pdu_phytest(int Mod_idP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
uint8_t *mcsIndex,
|
||||
uint16_t *rbSize,
|
||||
uint16_t *rbStart) {
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
@@ -271,9 +269,9 @@ int configure_fapi_dl_pdu(int Mod_idP,
|
||||
int bwp_id=1;
|
||||
int UE_id = 0;
|
||||
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->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);
|
||||
@@ -298,7 +296,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
|
||||
|
||||
|
||||
pdsch_pdu_rel15->pduBitmap = 0;
|
||||
pdsch_pdu_rel15->rnti = UE_list->rnti[UE_id];
|
||||
pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id];
|
||||
pdsch_pdu_rel15->pduIndex = 0;
|
||||
|
||||
// BWP
|
||||
@@ -310,17 +308,17 @@ int configure_fapi_dl_pdu(int Mod_idP,
|
||||
|
||||
pdsch_pdu_rel15->NrOfCodewords = 1;
|
||||
int mcs = (mcsIndex!=NULL) ? *mcsIndex : 9;
|
||||
int current_harq_pid = UE_list->UE_sched_ctrl[UE_id].current_harq_pid;
|
||||
int current_harq_pid = UE_info->UE_sched_ctrl[UE_id].current_harq_pid;
|
||||
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0);
|
||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||
pdsch_pdu_rel15->mcsIndex[0] = mcs;
|
||||
pdsch_pdu_rel15->mcsTable[0] = 0;
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round];
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round];
|
||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->nrOfLayers = 1;
|
||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||
pdsch_pdu_rel15->refPoint = 0; // Point A
|
||||
UE_list->mac_stats[UE_id].dlsch_rounds[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++;
|
||||
UE_info->mac_stats[UE_id].dlsch_rounds[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++;
|
||||
pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
|
||||
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->SCID = 0;
|
||||
@@ -368,18 +366,18 @@ int configure_fapi_dl_pdu(int Mod_idP,
|
||||
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
|
||||
// harq pid and ndi
|
||||
dci_pdu_rel15[0].harq_pid = current_harq_pid;
|
||||
dci_pdu_rel15[0].ndi = UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi;
|
||||
dci_pdu_rel15[0].ndi = UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi;
|
||||
// DAI
|
||||
dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3;
|
||||
|
||||
// TPC for PUCCH
|
||||
dci_pdu_rel15[0].tpc = UE_list->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
|
||||
dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
|
||||
// PUCCH resource indicator
|
||||
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
|
||||
// PDSCH to HARQ TI
|
||||
dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator;
|
||||
UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot;
|
||||
UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot;
|
||||
UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1;
|
||||
// antenna ports
|
||||
dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0
|
||||
// dmrs sequence initialization
|
||||
@@ -416,18 +414,30 @@ int configure_fapi_dl_pdu(int Mod_idP,
|
||||
}
|
||||
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
|
||||
|
||||
int ret = nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_list->rnti[UE_id],
|
||||
1, // ue-specific
|
||||
ss,
|
||||
scc,
|
||||
bwp);
|
||||
if (ret < 0) {
|
||||
LOG_I(MAC,"CCE list not empty, couldn't schedule PDSCH\n");
|
||||
free(dci_pdu_rel15);
|
||||
return (0);
|
||||
uint8_t nr_of_candidates, aggregation_level;
|
||||
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */);
|
||||
int CCEIndex = allocate_nr_CCEs(
|
||||
nr_mac,
|
||||
bwp,
|
||||
coreset,
|
||||
aggregation_level,
|
||||
UE_info->rnti[UE_id],
|
||||
0); // m
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PDSCH\n", __func__);
|
||||
free(dci_pdu_rel15);
|
||||
return 0;
|
||||
}
|
||||
nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_info->rnti[UE_id],
|
||||
ss,
|
||||
coreset,
|
||||
scc,
|
||||
bwp,
|
||||
aggregation_level,
|
||||
CCEIndex);
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
@@ -455,8 +465,8 @@ int configure_fapi_dl_pdu(int Mod_idP,
|
||||
|
||||
// Hardcode it for now
|
||||
TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0];
|
||||
if (UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0)
|
||||
UE_list->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
if (UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0)
|
||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
|
||||
LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
@@ -581,7 +591,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_info.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;
|
||||
@@ -608,14 +618,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
|
||||
mac_rlc_status_resp_t rlc_status;
|
||||
|
||||
NR_UE_list_t *UE_list = &gNB_mac->UE_list;
|
||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||
|
||||
if (UE_list->num_UEs ==0) return;
|
||||
if (UE_info->num_UEs ==0) return;
|
||||
|
||||
unsigned char sdu_lcids[NB_RB_MAX] = {0};
|
||||
uint16_t sdu_lengths[NB_RB_MAX] = {0};
|
||||
uint16_t rnti = UE_list->rnti[UE_id];
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
uint16_t rnti = UE_info->rnti[UE_id];
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
|
||||
|
||||
@@ -623,12 +633,13 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
|
||||
int ta_len = (ue_sched_ctl->ta_apply)?2:0;
|
||||
|
||||
TBS_bytes = configure_fapi_dl_pdu(module_idP,
|
||||
dl_req,
|
||||
pucch_sched,
|
||||
dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL,
|
||||
dlsch_config!=NULL ? &dlsch_config->rbSize : NULL,
|
||||
dlsch_config!=NULL ? &dlsch_config->rbStart : NULL);
|
||||
TBS_bytes = configure_fapi_dl_pdu_phytest(
|
||||
module_idP,
|
||||
dl_req,
|
||||
pucch_sched,
|
||||
dlsch_config != NULL ? dlsch_config->mcsIndex : NULL,
|
||||
dlsch_config != NULL ? &dlsch_config->rbSize : NULL,
|
||||
dlsch_config != NULL ? &dlsch_config->rbStart : NULL);
|
||||
|
||||
if (TBS_bytes == 0)
|
||||
return;
|
||||
@@ -693,7 +704,7 @@ 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) (lrand48()&0xff);
|
||||
//((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
|
||||
//((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff);
|
||||
}
|
||||
//Sending SDUs with size 1
|
||||
//Initialize elements of sdu_lcids and sdu_lengths
|
||||
@@ -707,13 +718,15 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
if (frameP%100 == 0){
|
||||
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
|
||||
for(int i = 0; i < 10; i++) {
|
||||
LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
|
||||
LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total;
|
||||
|
||||
// there is at least one SDU or TA command
|
||||
// if (num_sdus > 0 ){
|
||||
if (ta_len + sdu_length_total + header_length_total > 0) {
|
||||
@@ -730,8 +743,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
}
|
||||
|
||||
offset = nr_generate_dlsch_pdu(module_idP,
|
||||
&UE_info->UE_sched_ctrl[UE_id],
|
||||
(unsigned char *) mac_sdus,
|
||||
(unsigned char *) gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0],
|
||||
(unsigned char *) gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0],
|
||||
num_sdus, //num_sdus
|
||||
sdu_lengths,
|
||||
sdu_lcids,
|
||||
@@ -742,7 +756,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
// Padding: fill remainder of DLSCH with 0
|
||||
if (post_padding > 0){
|
||||
for (int j = 0; j < (TBS_bytes - offset); j++)
|
||||
gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0;
|
||||
gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0;
|
||||
}
|
||||
|
||||
configure_fapi_dl_Tx(module_idP, frameP, slotP, dl_req, tx_req, TBS_bytes, gNB_mac->pdu_index[CC_id]);
|
||||
@@ -759,7 +773,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
|
||||
if (frameP%100 == 0){
|
||||
LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
|
||||
for(int i = 0; i < 10; i++) {
|
||||
LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]);
|
||||
LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -800,12 +814,26 @@ int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
|
||||
DevAssert(ubwp);
|
||||
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
|
||||
if (tda_list->k2)
|
||||
return *tda_list->k2;
|
||||
else if (mu < 2)
|
||||
return 1;
|
||||
else if (mu == 2)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
|
||||
void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
int time_domain_assignment) {
|
||||
int time_domain_assignment,
|
||||
uint64_t ulsch_in_slot_bitmap) {
|
||||
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
@@ -814,10 +842,10 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
int bwp_id=1;
|
||||
int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
int UE_id = 0;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
|
||||
AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id);
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->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);
|
||||
@@ -829,18 +857,14 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
AssertFatal(time_domain_assignment<ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count,
|
||||
"time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count);
|
||||
|
||||
int K2;
|
||||
if (ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2 != NULL)
|
||||
K2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2;
|
||||
else {
|
||||
if (mu<2) K2=1;
|
||||
else if(mu==2) K2=2;
|
||||
else K2=3;
|
||||
}
|
||||
|
||||
if (is_xlsch_in_slot(UE_list->UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap,(slotP+K2)%num_slots_per_tdd)) {
|
||||
|
||||
//nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
|
||||
int K2 = get_K2(ubwp, time_domain_assignment,mu);
|
||||
/* check if slot is UL, and for phy test verify that it is in first TDD
|
||||
* period, slot 8 (for K2=2, this is at slot 6 in the gNB; because of UE
|
||||
* limitations). Note that if K2 or the TDD configuration is changed, below
|
||||
* conditions might exclude each other and never be true */
|
||||
const int slot_idx = (slotP + K2) % num_slots_per_tdd;
|
||||
if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot_idx)
|
||||
&& (!get_softmodem_params()->phy_test || slot_idx == 8)) {
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
|
||||
UL_dci_req->SFN = frameP;
|
||||
UL_dci_req->Slot = slotP;
|
||||
@@ -850,10 +874,10 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||
"searchPsacesToAddModList is empty\n");
|
||||
|
||||
uint16_t rnti = UE_list->rnti[UE_id];
|
||||
uint16_t rnti = UE_info->rnti[UE_id];
|
||||
|
||||
int first_ul_slot = num_slots_per_tdd - ul_slots;
|
||||
NR_sched_pusch *pusch_sched = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot];
|
||||
NR_sched_pusch *pusch_sched = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot];
|
||||
pusch_sched->frame = frameP;
|
||||
pusch_sched->slot = slotP + K2;
|
||||
pusch_sched->active = true;
|
||||
@@ -952,7 +976,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
if (get_softmodem_params()->phy_test==1)
|
||||
pusch_pdu->rb_size = 50;
|
||||
else
|
||||
pusch_pdu->rb_size = 5;
|
||||
pusch_pdu->rb_size = pusch_pdu->bwp_size;
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
|
||||
@@ -1045,9 +1069,9 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
|
||||
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
|
||||
//Optional Data only included if indicated in pduBitmap
|
||||
int8_t harq_id = select_ul_harq_pid(&UE_list->UE_sched_ctrl[UE_id]);
|
||||
int8_t harq_id = select_ul_harq_pid(&UE_info->UE_sched_ctrl[UE_id]);
|
||||
if (harq_id < 0) return;
|
||||
NR_UE_ul_harq_t *cur_harq = &UE_list->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id];
|
||||
NR_UE_ul_harq_t *cur_harq = &UE_info->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id];
|
||||
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
||||
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
|
||||
@@ -1077,8 +1101,8 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
0,
|
||||
pusch_pdu->nrOfLayers)>>3;
|
||||
|
||||
UE_list->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) UE_list->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size;
|
||||
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size;
|
||||
|
||||
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
|
||||
//pusch_pdu->pusch_data.cb_present_and_position;
|
||||
@@ -1099,22 +1123,34 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
|
||||
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
|
||||
|
||||
int ret = nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_list->rnti[UE_id],
|
||||
1, // ue-specific,
|
||||
ss,
|
||||
scc,
|
||||
bwp);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_I(MAC,"CCE list not empty, couldn't schedule PUSCH\n");
|
||||
uint8_t nr_of_candidates, aggregation_level;
|
||||
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */);
|
||||
int CCEIndex = allocate_nr_CCEs(
|
||||
nr_mac,
|
||||
bwp,
|
||||
coreset,
|
||||
aggregation_level,
|
||||
UE_info->rnti[UE_id],
|
||||
0); // m
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||
pusch_sched->active = false;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_info->rnti[UE_id],
|
||||
ss,
|
||||
coreset,
|
||||
scc,
|
||||
bwp,
|
||||
aggregation_level,
|
||||
CCEIndex);
|
||||
|
||||
dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t));
|
||||
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_list->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id);
|
||||
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_info->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id);
|
||||
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id);
|
||||
free(dci_pdu_rel15);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
#define ENABLE_MAC_PAYLOAD_DEBUG
|
||||
#define DEBUG_gNB_SCHEDULER 1
|
||||
|
||||
|
||||
#include "common/ran_context.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
@@ -127,37 +126,60 @@ static inline uint8_t get_max_cces(uint8_t scs) {
|
||||
return (nr_max_number_of_cces_per_slot[scs]);
|
||||
}
|
||||
|
||||
NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace_t *ss,
|
||||
int ss_type) {
|
||||
NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId;
|
||||
if (ss_type == 0) { // common search space
|
||||
AssertFatal(coreset_id != 0, "coreset0 currently not supported\n");
|
||||
NR_ControlResourceSet_t *coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
|
||||
AssertFatal(coreset_id == coreset->controlResourceSetId,
|
||||
"ID of common ss coreset does not correspond to id set in the "
|
||||
"search space\n");
|
||||
return coreset;
|
||||
} else {
|
||||
const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count;
|
||||
for (int i = 0; i < n; i++) {
|
||||
NR_ControlResourceSet_t *coreset =
|
||||
bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
|
||||
if (coreset_id == coreset->controlResourceSetId) {
|
||||
return coreset;
|
||||
}
|
||||
}
|
||||
AssertFatal(0, "Couldn't find coreset with id %ld\n", coreset_id);
|
||||
}
|
||||
}
|
||||
|
||||
NR_SearchSpace_t *get_searchspace(
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace__searchSpaceType_PR target_ss) {
|
||||
DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList);
|
||||
DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0);
|
||||
|
||||
const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;
|
||||
for (int i=0;i<n;i++) {
|
||||
NR_SearchSpace_t *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->searchSpaceType->present == target_ss) {
|
||||
return ss;
|
||||
}
|
||||
}
|
||||
AssertFatal(0, "Couldn't find an adequate searchspace\n");
|
||||
}
|
||||
|
||||
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
int bwp_id,
|
||||
int list_id,
|
||||
int aggregation,
|
||||
int search_space, // 0 common, 1 ue-specific
|
||||
int UE_id,
|
||||
int m) {
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
int aggregation,
|
||||
uint16_t n_RNTI,
|
||||
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;
|
||||
|
||||
NR_UE_list_t *UE_list = &nr_mac->UE_list;
|
||||
|
||||
NR_BWP_Downlink_t *bwp;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup;
|
||||
|
||||
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) {
|
||||
coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[list_id];
|
||||
}
|
||||
else {
|
||||
coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
|
||||
}
|
||||
|
||||
int coreset_id = coreset->controlResourceSetId;
|
||||
int *cce_list = nr_mac->cce_list[bwp_id][coreset_id];
|
||||
int *cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id];
|
||||
|
||||
int n_rb=0;
|
||||
for (int i=0;i<6;i++)
|
||||
@@ -167,17 +189,14 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
n_rb*=6;
|
||||
|
||||
uint16_t N_reg = n_rb * coreset->duration;
|
||||
uint16_t Y=0, N_cce, M_s_max, n_CI=0;
|
||||
uint16_t n_RNTI = search_space == 1 ? UE_list->rnti[UE_id]:0;
|
||||
uint32_t A[3]={39827,39829,39839};
|
||||
uint16_t n_CI=0;
|
||||
const uint32_t A[3]={39827,39829,39839};
|
||||
/* if n_RNTI is zero, this results in zero, too! */
|
||||
uint16_t Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0
|
||||
|
||||
N_cce = N_reg / NR_NB_REG_PER_CCE;
|
||||
uint16_t N_cce = N_reg / NR_NB_REG_PER_CCE;
|
||||
|
||||
M_s_max = (aggregation==4)?4:(aggregation==8)?2:1;
|
||||
|
||||
if (search_space == 1) {
|
||||
Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0
|
||||
}
|
||||
uint16_t M_s_max = (aggregation==4)?4:(aggregation==8)?2:1;
|
||||
int first_cce = aggregation * (( Y + (m*N_cce)/(aggregation*M_s_max) + n_CI ) % CEILIDIV(N_cce,aggregation));
|
||||
|
||||
for (int i=0;i<aggregation;i++)
|
||||
@@ -407,44 +426,229 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
|
||||
|
||||
}
|
||||
|
||||
int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
|
||||
uint16_t rnti,
|
||||
int ss_type,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Downlink_t *bwp){
|
||||
void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
int UE_id,
|
||||
int bwp_id,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
int nrOfLayers,
|
||||
uint8_t mcs,
|
||||
uint16_t rbSize,
|
||||
uint16_t rbStart,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
nfapi_nr_dmrs_type_e dmrsConfigType,
|
||||
uint8_t table_idx,
|
||||
uint16_t R,
|
||||
uint8_t Qm,
|
||||
uint32_t TBS,
|
||||
int time_domain_assignment,
|
||||
int StartSymbolIndex,
|
||||
int NrOfSymbols,
|
||||
uint8_t aggregation_level,
|
||||
int CCEIndex,
|
||||
int harq_pid,
|
||||
int ndi,
|
||||
int round) {
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
|
||||
int CCEIndex = -1;
|
||||
int cid = 0;
|
||||
NR_ControlResourceSet_t *coreset = NULL;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->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[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");
|
||||
|
||||
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;
|
||||
|
||||
|
||||
pdsch_pdu_rel15->pduBitmap = 0;
|
||||
pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id];
|
||||
pdsch_pdu_rel15->pduIndex = nr_mac->pdu_index[0]++;
|
||||
|
||||
// BWP
|
||||
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;
|
||||
if (bwp->bwp_Common->genericParameters.cyclicPrefix)
|
||||
pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix;
|
||||
else
|
||||
pdsch_pdu_rel15->CyclicPrefix = 0;
|
||||
|
||||
pdsch_pdu_rel15->NrOfCodewords = 1;
|
||||
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0);
|
||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||
pdsch_pdu_rel15->mcsIndex[0] = mcs;
|
||||
pdsch_pdu_rel15->mcsTable[0] = 0;
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[round];
|
||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->nrOfLayers = nrOfLayers;
|
||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||
pdsch_pdu_rel15->refPoint = 0; // Point A
|
||||
pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType;
|
||||
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->SCID = 0;
|
||||
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData;
|
||||
pdsch_pdu_rel15->dmrsPorts = 1;
|
||||
pdsch_pdu_rel15->resourceAlloc = 1;
|
||||
pdsch_pdu_rel15->rbStart = rbStart;
|
||||
pdsch_pdu_rel15->rbSize = rbSize;
|
||||
pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
|
||||
pdsch_pdu_rel15->targetCodeRate[0] = R;
|
||||
pdsch_pdu_rel15->qamModOrder[0] = Qm;
|
||||
pdsch_pdu_rel15->TBSize[0] = TBS;
|
||||
pdsch_pdu_rel15->mcsTable[0] = table_idx;
|
||||
pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
|
||||
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
|
||||
|
||||
// k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0;
|
||||
pdsch_pdu_rel15->dlDmrsSymbPos =
|
||||
fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup,
|
||||
scc->dmrs_TypeA_Position,
|
||||
pdsch_pdu_rel15->NrOfSymbols);
|
||||
|
||||
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
|
||||
memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t) * MAX_DCI_CORESET);
|
||||
|
||||
// bwp indicator
|
||||
int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
|
||||
if (n_dl_bwp < 4)
|
||||
dci_pdu_rel15[0].bwp_indicator.val = bwp_id;
|
||||
else
|
||||
dci_pdu_rel15[0].bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
|
||||
// frequency domain assignment
|
||||
if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation==NR_PDSCH_Config__resourceAllocation_resourceAllocationType1)
|
||||
dci_pdu_rel15[0].frequency_domain_assignment.val =
|
||||
PRBalloc_to_locationandbandwidth0(
|
||||
pdsch_pdu_rel15->rbSize,
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,
|
||||
275));
|
||||
else
|
||||
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
|
||||
// time domain assignment
|
||||
dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV;
|
||||
// mcs and rv
|
||||
dci_pdu_rel15[0].mcs = mcs;
|
||||
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
|
||||
// harq pid and ndi
|
||||
dci_pdu_rel15[0].harq_pid = harq_pid;
|
||||
dci_pdu_rel15[0].ndi = ndi;
|
||||
// DAI
|
||||
dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3;
|
||||
|
||||
// TPC for PUCCH
|
||||
dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
|
||||
// PUCCH resource indicator
|
||||
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
|
||||
// PDSCH to HARQ TI
|
||||
dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator;
|
||||
// antenna ports
|
||||
dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0
|
||||
// dmrs sequence initialization
|
||||
dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID;
|
||||
LOG_D(MAC,
|
||||
"[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), "
|
||||
"time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
|
||||
dci_pdu_rel15[0].frequency_domain_assignment.val,
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
pdsch_pdu_rel15->rbSize,
|
||||
NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, 275),
|
||||
dci_pdu_rel15[0].time_domain_assignment.val,
|
||||
dci_pdu_rel15[0].vrb_to_prb_mapping.val,
|
||||
dci_pdu_rel15[0].mcs,
|
||||
dci_pdu_rel15[0].tb_scaling,
|
||||
dci_pdu_rel15[0].ndi,
|
||||
dci_pdu_rel15[0].rv);
|
||||
|
||||
nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_info->rnti[UE_id],
|
||||
ss,
|
||||
coreset,
|
||||
scc,
|
||||
bwp,
|
||||
aggregation_level,
|
||||
CCEIndex);
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
|
||||
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;
|
||||
|
||||
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id);
|
||||
|
||||
LOG_D(MAC,
|
||||
"DCI params: rnti %x, rnti_type %d, dci_format %d\n",
|
||||
pdcch_pdu_rel15->dci_pdu.RNTI[0],
|
||||
rnti_types[0],
|
||||
dci_formats[0]);
|
||||
LOG_D(MAC,
|
||||
"coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
|
||||
(unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
|
||||
pdcch_pdu_rel15->StartSymbolIndex,
|
||||
pdcch_pdu_rel15->DurationSymbols);
|
||||
|
||||
// I don't know why the following is not needed, but in this case we don't
|
||||
// need additional calculations:
|
||||
//const uint16_t N_RE_prime = NR_NB_SC_PER_RB * N_sh_symb - N_PRB_DMRS - N_PRB_oh;
|
||||
//LOG_D(MAC,
|
||||
// "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n",
|
||||
// N_RE_prime,
|
||||
// N_sh_symb,
|
||||
// N_PRB_DMRS,
|
||||
// N_PRB_oh);
|
||||
//pdsch_pdu_rel15->nb_mod_symbols = N_RE_prime*pdsch_pdu_rel15->n_prb*pdsch_pdu_rel15->nb_codewords;
|
||||
|
||||
LOG_D(MAC,
|
||||
"DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d "
|
||||
"nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
pdsch_pdu_rel15->rbSize,
|
||||
pdsch_pdu_rel15->StartSymbolIndex,
|
||||
pdsch_pdu_rel15->NrOfSymbols,
|
||||
pdsch_pdu_rel15->nrOfLayers,
|
||||
pdsch_pdu_rel15->NrOfCodewords,
|
||||
pdsch_pdu_rel15->mcsIndex[0],
|
||||
TBS);
|
||||
|
||||
dl_req->nPDUs += 2;
|
||||
}
|
||||
|
||||
void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
uint16_t rnti,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
uint8_t aggregation_level,
|
||||
int CCEIndex) {
|
||||
if (bwp) { // This is not the InitialBWP
|
||||
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; i<n_list; i++) {
|
||||
temp_coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i];
|
||||
if (coresetid==temp_coreset->controlResourceSetId) {
|
||||
coreset = temp_coreset;
|
||||
cid = i;
|
||||
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;
|
||||
@@ -507,22 +711,6 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
pdcch_pdu->dci_pdu.ScramblingRNTI[pdcch_pdu->numDlDci]=0;
|
||||
}
|
||||
|
||||
uint8_t nr_of_candidates,aggregation_level;
|
||||
find_aggregation_candidates(&aggregation_level,
|
||||
&nr_of_candidates,
|
||||
ss);
|
||||
|
||||
CCEIndex = allocate_nr_CCEs(nr_mac,
|
||||
1, // bwp_id
|
||||
cid,
|
||||
aggregation_level,
|
||||
ss->searchSpaceType->present-1, // search_space, 0 common, 1 ue-specific
|
||||
0, // UE-id
|
||||
0); // m
|
||||
|
||||
if (CCEIndex<0)
|
||||
return (CCEIndex);
|
||||
|
||||
pdcch_pdu->dci_pdu.AggregationLevel[pdcch_pdu->numDlDci] = aggregation_level;
|
||||
pdcch_pdu->dci_pdu.CceIndex[pdcch_pdu->numDlDci] = CCEIndex;
|
||||
|
||||
@@ -531,7 +719,6 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
|
||||
pdcch_pdu->dci_pdu.powerControlOffsetSS[pdcch_pdu->numDlDci]=1;
|
||||
pdcch_pdu->numDlDci++;
|
||||
return (0);
|
||||
}
|
||||
else { // this is for InitialBWP
|
||||
AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n");
|
||||
@@ -1396,39 +1583,34 @@ int extract_length(int startSymbolAndLength) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump the UL or DL UE_list into LOG_T(MAC)
|
||||
* Dump the UL or DL UE_info into LOG_T(MAC)
|
||||
*/
|
||||
void
|
||||
dump_nr_ue_list(NR_UE_list_t *listP,
|
||||
int ul_flag)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
if (ul_flag == 0) {
|
||||
for (int j = listP->head; j >= 0; j = listP->next[j]) {
|
||||
LOG_T(MAC, "DL list node %d => %d\n",
|
||||
j,
|
||||
listP->next[j]);
|
||||
}
|
||||
} else {
|
||||
for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) {
|
||||
LOG_T(MAC, "UL list node %d => %d\n",
|
||||
j,
|
||||
listP->next_ul[j]);
|
||||
}
|
||||
}
|
||||
void dump_nr_ue_list(NR_UE_list_t *listP) {
|
||||
for (int j = listP->head; j >= 0; j = listP->next[j])
|
||||
LOG_T(MAC, "DL list node %d => %d\n", j, listP->next[j]);
|
||||
}
|
||||
|
||||
return;
|
||||
/*
|
||||
* Add a UE to NR_UE_list listP
|
||||
*/
|
||||
inline void add_nr_ue_list(NR_UE_list_t *listP, int UE_id) {
|
||||
int *cur = &listP->head;
|
||||
while (*cur >= 0) {
|
||||
AssertFatal(*cur != UE_id, "UE_id %d already in NR_UE_list!\n", UE_id);
|
||||
cur = &listP->next[*cur];
|
||||
}
|
||||
*cur = UE_id;
|
||||
}
|
||||
|
||||
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int UE_id;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
|
||||
|
||||
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
|
||||
if (UE_list->active[UE_id] == TRUE) {
|
||||
if (UE_list->rnti[UE_id] == rntiP) {
|
||||
if (UE_info->active[UE_id]) {
|
||||
if (UE_info->rnti[UE_id] == rntiP) {
|
||||
return UE_id;
|
||||
}
|
||||
}
|
||||
@@ -1439,42 +1621,40 @@ 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 UE_id;
|
||||
int i;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
|
||||
NR_COMMON_channels_t *cc = RC.nrmac[mod_idP]->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
int num_slots_ul = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
|
||||
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0)
|
||||
num_slots_ul++;
|
||||
LOG_I(MAC, "[gNB %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",
|
||||
LOG_W(MAC, "[gNB %d] Adding UE with rnti %x (num_UEs %d)\n",
|
||||
mod_idP,
|
||||
rntiP,
|
||||
UE_list->avail,
|
||||
UE_list->num_UEs);
|
||||
dump_nr_ue_list(UE_list, 0);
|
||||
UE_info->num_UEs);
|
||||
dump_nr_ue_list(&UE_info->list);
|
||||
|
||||
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_list->active[i] == TRUE)
|
||||
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_info->active[i])
|
||||
continue;
|
||||
|
||||
UE_id = i;
|
||||
UE_list->num_UEs++;
|
||||
UE_list->active[UE_id] = TRUE;
|
||||
UE_list->rnti[UE_id] = rntiP;
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
|
||||
int UE_id = i;
|
||||
UE_info->num_UEs++;
|
||||
UE_info->active[UE_id] = true;
|
||||
UE_info->rnti[UE_id] = rntiP;
|
||||
add_nr_ue_list(&UE_info->list, UE_id);
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
|
||||
0,
|
||||
sizeof(NR_UE_sched_ctrl_t));
|
||||
UE_list->UE_sched_ctrl[UE_id].ta_timer = 100;
|
||||
UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
|
||||
UE_list->UE_sched_ctrl[UE_id].ul_rssi = 0;
|
||||
UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
|
||||
UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_timer = 100;
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_update = 31;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0;
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
|
||||
for (int k=0; k<num_slots_ul; k++) {
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pusch));
|
||||
}
|
||||
@@ -1482,15 +1662,13 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
|
||||
mod_idP,
|
||||
UE_id,
|
||||
rntiP);
|
||||
dump_nr_ue_list(UE_list,
|
||||
0);
|
||||
dump_nr_ue_list(&UE_info->list);
|
||||
return (UE_id);
|
||||
}
|
||||
|
||||
// printf("MAC: cannot add new UE for rnti %x\n", rntiP);
|
||||
LOG_E(MAC, "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
|
||||
dump_nr_ue_list(UE_list,
|
||||
0);
|
||||
LOG_E(MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n");
|
||||
dump_nr_ue_list(&UE_info->list);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1503,23 +1681,23 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
|
||||
{
|
||||
int UE_id;
|
||||
int i;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[mod_id]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
|
||||
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_list->active[i] != TRUE)
|
||||
if (UE_info->active[i] != TRUE)
|
||||
continue;
|
||||
if (UE_list->rnti[i] != rnti)
|
||||
if (UE_info->rnti[i] != rnti)
|
||||
continue;
|
||||
|
||||
/* UE found, remove it */
|
||||
UE_id = i;
|
||||
UE_list->num_UEs--;
|
||||
UE_list->UEcontext[UE_id].fiveG_connected = FALSE;
|
||||
UE_list->active[UE_id] = FALSE;
|
||||
UE_list->rnti[UE_id] = 0;
|
||||
free(UE_list->UE_sched_ctrl[UE_id].sched_pucch);
|
||||
free(UE_list->UE_sched_ctrl[UE_id].sched_pusch);
|
||||
memset((void *) &UE_list->UE_sched_ctrl[UE_id],
|
||||
|
||||
UE_info->num_UEs--;
|
||||
UE_info->active[UE_id] = FALSE;
|
||||
UE_info->rnti[UE_id] = 0;
|
||||
free(UE_info->UE_sched_ctrl[UE_id].sched_pucch);
|
||||
free(UE_info->UE_sched_ctrl[UE_id].sched_pusch);
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
|
||||
0,
|
||||
sizeof(NR_UE_sched_ctrl_t));
|
||||
LOG_I(MAC, "[gNB %d] Remove NR UE_id %d : rnti %x\n",
|
||||
@@ -1554,8 +1732,8 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
|
||||
uint8_t *pdsch_to_harq_feedback) {
|
||||
|
||||
int bwp_id=1;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
|
||||
@@ -1607,7 +1785,7 @@ void nr_update_pucch_scheduling(int Mod_idP,
|
||||
int *pucch_id) {
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_sched_pucch *curr_pucch;
|
||||
int first_ul_slot_tdd,k,i;
|
||||
uint8_t pdsch_to_harq_feedback[8];
|
||||
@@ -1622,7 +1800,7 @@ void nr_update_pucch_scheduling(int Mod_idP,
|
||||
|
||||
// for each possible ul or mixed slot
|
||||
for (k=0; k<nr_ulmix_slots; k++) {
|
||||
curr_pucch = &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k];
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k];
|
||||
// if there is free room in current pucch structure
|
||||
if (curr_pucch->dai_c<MAX_ACK_BITS) {
|
||||
curr_pucch->frame = frameP;
|
||||
|
||||
@@ -212,7 +212,7 @@ void nr_process_mac_pdu(
|
||||
|
||||
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);
|
||||
int UE_id = find_nr_UE_id(module_idP, rnti);
|
||||
RC.nrmac[module_idP]->UE_list.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
|
||||
RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
|
||||
|
||||
@@ -309,19 +309,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
const uint16_t rssi){
|
||||
int current_rnti = 0, UE_id = -1, harq_pid = 0;
|
||||
gNB_MAC_INST *gNB_mac = NULL;
|
||||
NR_UE_list_t *UE_list = NULL;
|
||||
NR_UE_info_t *UE_info = NULL;
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = NULL;
|
||||
|
||||
current_rnti = rntiP;
|
||||
UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti);
|
||||
gNB_mac = RC.nrmac[gnb_mod_idP];
|
||||
UE_list = &gNB_mac->UE_list;
|
||||
UE_info = &gNB_mac->UE_info;
|
||||
int target_snrx10 = gNB_mac->pusch_target_snrx10;
|
||||
|
||||
if (UE_id != -1) {
|
||||
UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
|
||||
UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
|
||||
|
||||
UE_list->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
|
||||
UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
|
||||
LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
|
||||
gnb_mod_idP,
|
||||
harq_pid,
|
||||
@@ -364,20 +364,46 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (sduP != NULL) { // if the CRC passed
|
||||
// random access pusch with TC-RNTI
|
||||
if (sduP != NULL) { // if the CRC passed
|
||||
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_list->active[i] == TRUE) {
|
||||
if (UE_list->tc_rnti[i] == current_rnti) {
|
||||
// for now the only thing we are doing is set the UE as 5G connected
|
||||
UE_list->UEcontext[i].fiveG_connected = true;
|
||||
LOG_I(MAC, "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly and UE_id %d is now 5G connected\n",
|
||||
gnb_mod_idP, current_rnti, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0];
|
||||
if (ra->state != WAIT_Msg3) {
|
||||
LOG_E(MAC,
|
||||
"expected RA state WAIT_Msg3/%d (but is %d) for RA-RNTI %04x\n",
|
||||
WAIT_Msg3,
|
||||
ra->state,
|
||||
ra->rnti);
|
||||
return;
|
||||
}
|
||||
if (ra->rnti != current_rnti) {
|
||||
LOG_E(MAC,
|
||||
"expected RA-RNTI %04x (C-RNTI %04x) to match current RNTI %04x\n",
|
||||
ra->rnti,
|
||||
ra->crnti,
|
||||
current_rnti);
|
||||
return;
|
||||
|
||||
}
|
||||
free(ra->preambles.preamble_list);
|
||||
ra->state = RA_IDLE;
|
||||
LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti);
|
||||
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->crnti);
|
||||
UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup;
|
||||
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
|
||||
ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
|
||||
AssertFatal(bwpList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
bwpList->list.count);
|
||||
const int bwp_id = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
|
||||
LOG_W(MAC,
|
||||
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
|
||||
"adding UE MAC Context UE_id %d/RNTI %04x\n",
|
||||
gnb_mod_idP,
|
||||
current_rnti,
|
||||
UE_id,
|
||||
ra->crnti);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame_rxP, sub_frame_t slot_rxP);
|
||||
|
||||
int nr_generate_dlsch_pdu(module_id_t Mod_idP,
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl,
|
||||
unsigned char *sdus_payload,
|
||||
unsigned char *mac_pdu,
|
||||
unsigned char num_sdus,
|
||||
@@ -76,7 +77,10 @@ int nr_generate_dlsch_pdu(module_id_t Mod_idP,
|
||||
unsigned char *ue_cont_res_id,
|
||||
unsigned short post_padding);
|
||||
|
||||
void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
|
||||
void nr_schedule_ue_spec(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
|
||||
|
||||
@@ -126,12 +130,38 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t subframeP);
|
||||
|
||||
int configure_fapi_dl_pdu(int Mod_id,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
uint8_t *mcsIndex,
|
||||
uint16_t *rbSize,
|
||||
uint16_t *rbStart);
|
||||
void nr_fill_nfapi_dl_pdu(int Mod_id,
|
||||
int UE_id,
|
||||
int bwp_id,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
int nrOfLayers,
|
||||
uint8_t mcs,
|
||||
uint16_t rbSize,
|
||||
uint16_t rbStart,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
nfapi_nr_dmrs_type_e dmrsConfigType,
|
||||
uint8_t table_idx,
|
||||
uint16_t R,
|
||||
uint8_t Qm,
|
||||
uint32_t tbs,
|
||||
int time_domain_assignment,
|
||||
int StartSymbolIndex,
|
||||
int NrOfSymbols,
|
||||
uint8_t aggregation_level,
|
||||
int CCEIndex,
|
||||
int harq_pid,
|
||||
int ndi,
|
||||
int round);
|
||||
|
||||
int configure_fapi_dl_pdu_phytest(int Mod_id,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_sched_pucch *pucch_sched,
|
||||
uint8_t *mcsIndex,
|
||||
uint16_t *rbSize,
|
||||
uint16_t *rbStart);
|
||||
|
||||
void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
@@ -211,13 +241,15 @@ void find_search_space(int ss_type,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace_t *ss);
|
||||
|
||||
int nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
|
||||
uint16_t rnti,
|
||||
int ss_type,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Downlink_t *bwp);
|
||||
void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
uint16_t rnti,
|
||||
NR_SearchSpace_t *ss,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
uint8_t aggregation_level,
|
||||
int CCEIndex);
|
||||
|
||||
void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
@@ -233,6 +265,16 @@ void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
nr_dci_format_t format,
|
||||
int bwp_id);
|
||||
|
||||
/* find coreset within the search space */
|
||||
NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace_t *ss,
|
||||
int ss_type);
|
||||
|
||||
/* find a search space within a BWP */
|
||||
NR_SearchSpace_t *get_searchspace(
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace__searchSpaceType_PR target_ss);
|
||||
|
||||
void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
NR_SearchSpace_t *ss);
|
||||
@@ -259,7 +301,8 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB);
|
||||
|
||||
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
|
||||
|
||||
void dump_nr_ue_list(NR_UE_list_t *listP, int ul_flag);
|
||||
void dump_nr_ue_list(NR_UE_list_t *listP);
|
||||
void add_nr_ue_list(NR_UE_list_t *listP, int UE_id);
|
||||
|
||||
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
|
||||
|
||||
@@ -268,13 +311,11 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
|
||||
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
|
||||
|
||||
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
int bwp_id,
|
||||
int coreset_id,
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_ControlResourceSet_t *coreset,
|
||||
int aggregation,
|
||||
int search_space, // 0 common, 1 ue-specific
|
||||
int UE_id,
|
||||
int m
|
||||
);
|
||||
uint16_t n_RNTI,
|
||||
int m);
|
||||
|
||||
int get_dlscs(nfapi_nr_config_request_t *cfg);
|
||||
|
||||
@@ -307,7 +348,8 @@ void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
sub_frame_t slotP,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
int time_domain_assignment);
|
||||
int time_domain_assignment,
|
||||
uint64_t ulsch_in_slot_bitmap);
|
||||
|
||||
void nr_process_mac_pdu(
|
||||
module_id_t module_idP,
|
||||
|
||||
@@ -50,7 +50,7 @@ void mac_top_init_gNB(void)
|
||||
{
|
||||
module_id_t i;
|
||||
int list_el;
|
||||
NR_UE_list_t *UE_list;
|
||||
NR_UE_info_t *UE_info;
|
||||
gNB_MAC_INST *nrmac;
|
||||
|
||||
LOG_I(MAC, "[MAIN] Init function start:nb_nr_macrlc_inst=%d\n",RC.nb_nr_macrlc_inst);
|
||||
@@ -104,29 +104,21 @@ void mac_top_init_gNB(void)
|
||||
nrmac = RC.nrmac[i];
|
||||
nrmac->if_inst = NR_IF_Module_init(i);
|
||||
|
||||
UE_list = &nrmac->UE_list;
|
||||
UE_list->num_UEs = 0;
|
||||
UE_list->head = -1;
|
||||
UE_list->head_ul = -1;
|
||||
UE_list->avail = 0;
|
||||
|
||||
for (list_el = 0; list_el < MAX_MOBILES_PER_GNB - 1; list_el++) {
|
||||
UE_list->next[list_el] = list_el + 1;
|
||||
UE_list->next_ul[list_el] = list_el + 1;
|
||||
UE_list->active[list_el] = FALSE;
|
||||
UE_info = &nrmac->UE_info;
|
||||
UE_info->num_UEs = 0;
|
||||
UE_info->list.head = -1;
|
||||
for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) {
|
||||
UE_info->list.next[list_el] = -1;
|
||||
UE_info->active[list_el] = false;
|
||||
for (int list_harq = 0; list_harq < NR_MAX_NB_HARQ_PROCESSES; list_harq++) {
|
||||
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0;
|
||||
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0;
|
||||
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0;
|
||||
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0;
|
||||
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0;
|
||||
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0;
|
||||
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0;
|
||||
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0;
|
||||
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0;
|
||||
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0;
|
||||
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0;
|
||||
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
UE_list->next[list_el] = -1;
|
||||
UE_list->next_ul[list_el] = -1;
|
||||
UE_list->active[list_el] = FALSE;
|
||||
}
|
||||
|
||||
srand48(0);
|
||||
|
||||
@@ -86,6 +86,11 @@ typedef enum {
|
||||
WAIT_Msg4_ACK = 4
|
||||
} RA_gNB_state_t;
|
||||
|
||||
typedef struct NR_preamble_ue {
|
||||
uint8_t num_preambles;
|
||||
uint8_t *preamble_list;
|
||||
} NR_preamble_ue_t;
|
||||
|
||||
/*! \brief gNB template for the Random access information */
|
||||
typedef struct {
|
||||
/// Flag to indicate this process is active
|
||||
@@ -144,6 +149,12 @@ typedef struct {
|
||||
int msg4_mcs;
|
||||
/// RA search space
|
||||
NR_SearchSpace_t *ra_ss;
|
||||
/// secondaryCellGroup for UE in NSA that is to come
|
||||
NR_CellGroupConfig_t *secondaryCellGroup;
|
||||
/// Preambles for contention-free access
|
||||
NR_preamble_ue_t preambles;
|
||||
/// NSA: the UEs C-RNTI to use
|
||||
rnti_t crnti;
|
||||
} NR_RA_t;
|
||||
|
||||
/*! \brief gNB common channels */
|
||||
@@ -175,9 +186,9 @@ typedef struct {
|
||||
/// Template for RA computations
|
||||
NR_RA_t ra[NR_NB_RA_PROC_MAX];
|
||||
/// VRB map for common channels
|
||||
uint8_t vrb_map[100];
|
||||
uint8_t vrb_map[275];
|
||||
/// VRB map for common channels and retransmissions by PHICH
|
||||
uint8_t vrb_map_UL[100];
|
||||
uint8_t vrb_map_UL[275];
|
||||
/// number of subframe allocation pattern available for MBSFN sync area
|
||||
uint8_t num_sf_allocation_pattern;
|
||||
} NR_COMMON_channels_t;
|
||||
@@ -271,6 +282,14 @@ typedef struct NR_UE_harq {
|
||||
uint16_t feedback_slot;
|
||||
} NR_UE_harq_t;
|
||||
|
||||
typedef struct NR_UE_old_sched {
|
||||
uint16_t rbSize;
|
||||
int time_domain_allocation;
|
||||
uint8_t mcsTableIdx;
|
||||
uint8_t mcs;
|
||||
uint8_t numDmrsCdmGrpsNoData;
|
||||
} NR_UE_ret_info_t;
|
||||
|
||||
typedef enum {
|
||||
INACTIVE = 0,
|
||||
ACTIVE_NOT_SCHED,
|
||||
@@ -286,10 +305,39 @@ typedef struct NR_UE_ul_harq {
|
||||
|
||||
/*! \brief scheduling control information set through an API */
|
||||
typedef struct {
|
||||
uint64_t dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch
|
||||
uint64_t ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch
|
||||
/// total amount of data awaiting for this UE
|
||||
uint32_t num_total_bytes;
|
||||
/// per-LC status data
|
||||
mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
|
||||
|
||||
/// the currently active BWP in DL
|
||||
NR_BWP_Downlink_t *active_bwp;
|
||||
NR_sched_pucch *sched_pucch;
|
||||
/// selected PUCCH index, if scheduled
|
||||
int pucch_sched_idx;
|
||||
NR_sched_pusch *sched_pusch;
|
||||
|
||||
/// CCE index and aggregation, should be coherent with cce_list
|
||||
NR_SearchSpace_t *search_space;
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
int cce_index;
|
||||
uint8_t aggregation_level;
|
||||
|
||||
/// RB allocation within active BWP
|
||||
uint16_t rbSize;
|
||||
uint16_t rbStart;
|
||||
|
||||
// time-domain allocation for scheduled RBs
|
||||
int time_domain_allocation;
|
||||
|
||||
/// MCS-related infos
|
||||
uint8_t mcsTableIdx;
|
||||
uint8_t mcs;
|
||||
uint8_t numDmrsCdmGrpsNoData;
|
||||
|
||||
/// Retransmission-related information
|
||||
NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
|
||||
|
||||
uint16_t ta_timer;
|
||||
int16_t ta_update;
|
||||
bool ta_apply;
|
||||
@@ -303,11 +351,6 @@ typedef struct {
|
||||
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
|
||||
} NR_UE_sched_ctrl_t;
|
||||
|
||||
typedef struct NR_preamble_ue {
|
||||
uint8_t num_preambles;
|
||||
uint8_t *preamble_list;
|
||||
} NR_preamble_ue;
|
||||
|
||||
typedef struct {
|
||||
boolean_t fiveG_connected;
|
||||
uicc_t *uicc;
|
||||
@@ -326,25 +369,28 @@ typedef struct {
|
||||
} NR_mac_stats_t;
|
||||
|
||||
|
||||
|
||||
/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in
|
||||
* the scheduler and to keep "classes" of users. */
|
||||
typedef struct {
|
||||
int head;
|
||||
int next[MAX_MOBILES_PER_GNB];
|
||||
} NR_UE_list_t;
|
||||
|
||||
|
||||
/*! \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];
|
||||
NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
|
||||
int next[MAX_MOBILES_PER_GNB];
|
||||
int head;
|
||||
int next_ul[MAX_MOBILES_PER_GNB];
|
||||
int head_ul;
|
||||
int avail;
|
||||
NR_UE_list_t list;
|
||||
int num_UEs;
|
||||
boolean_t active[MAX_MOBILES_PER_GNB];
|
||||
NRUEcontext_t UEcontext[MAX_MOBILES_PER_GNB];
|
||||
|
||||
bool active[MAX_MOBILES_PER_GNB];
|
||||
rnti_t rnti[MAX_MOBILES_PER_GNB];
|
||||
rnti_t tc_rnti[MAX_MOBILES_PER_GNB];
|
||||
NR_preamble_ue preambles[MAX_MOBILES_PER_GNB];
|
||||
NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB];
|
||||
} NR_UE_list_t;
|
||||
} NR_UE_info_t;
|
||||
|
||||
/*! \brief top level eNB MAC structure */
|
||||
typedef struct gNB_MAC_INST_s {
|
||||
@@ -378,7 +424,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
/// NFAPI DL PDU structure
|
||||
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
|
||||
|
||||
NR_UE_list_t UE_list;
|
||||
NR_UE_info_t UE_info;
|
||||
|
||||
/// UL handle
|
||||
uint32_t ul_handle;
|
||||
|
||||
@@ -431,9 +431,9 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
|
||||
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
|
||||
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti;
|
||||
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4;
|
||||
printf("!!!!!!! deliver_sdu_drb (drb %d) sending message to gtp size %d: ", rb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
|
||||
printf("\n");
|
||||
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
|
||||
//printf("\n");
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
|
||||
|
||||
}
|
||||
@@ -474,9 +474,9 @@ rb_found:
|
||||
memblock = get_free_mem_block(size, __FUNCTION__);
|
||||
memcpy(memblock->data, buf, size);
|
||||
|
||||
printf("!!!!!!! deliver_pdu_drb (srb %d) calling rlc_data_req size %d: ", rb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
|
||||
printf("\n");
|
||||
LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
|
||||
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
|
||||
//printf("\n");
|
||||
enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -877,7 +877,7 @@ static boolean_t pdcp_data_req_drb(
|
||||
const sdu_size_t sdu_buffer_size,
|
||||
unsigned char *const sdu_buffer)
|
||||
{
|
||||
printf("pdcp_data_req called size %d\n", sdu_buffer_size);
|
||||
LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size);
|
||||
nr_pdcp_ue_t *ue;
|
||||
nr_pdcp_entity_t *rb;
|
||||
int rnti = ctxt_pP->rnti;
|
||||
|
||||
@@ -181,10 +181,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot);
|
||||
handle_nr_rach(UL_info);
|
||||
|
||||
handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0],mac->pucch_target_snrx10);
|
||||
handle_nr_uci(UL_info,&mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0],mac->pucch_target_snrx10);
|
||||
// clear HI prior to handling ULSCH
|
||||
mac->UL_dci_req[CC_id].numPdus = 0;
|
||||
handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0]);
|
||||
handle_nr_ulsch(UL_info, &mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0]);
|
||||
|
||||
if (nfapi_mode != 1) {
|
||||
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
|
||||
|
||||
@@ -107,17 +107,10 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
|
||||
module_id_t module_id = ul_info->module_id;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
|
||||
// clean previous FAPI messages
|
||||
mac->tx_request.number_of_pdus = 0;
|
||||
mac->ul_config_request.number_pdus = 0;
|
||||
mac->dl_config_request.number_pdus = 0;
|
||||
// clean previous FAPI messages
|
||||
|
||||
ret = nr_ue_scheduler(NULL, ul_info);
|
||||
|
||||
if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra){
|
||||
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);
|
||||
}
|
||||
|
||||
switch(ret){
|
||||
case UE_CONNECTION_OK:
|
||||
@@ -132,8 +125,6 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
|
||||
break;
|
||||
}
|
||||
|
||||
mac->if_module->scheduled_response(&mac->scheduled_response);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -151,22 +142,11 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
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; i<dl_info->dci_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);
|
||||
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
int8_t ret = handle_dci(dl_info->module_id,
|
||||
dl_info->cc_id,
|
||||
dl_info->gNB_index,
|
||||
@@ -174,8 +154,10 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
||||
|
||||
ret_mask |= (ret << FAPI_NR_DCI_IND);
|
||||
if (ret >= 0) {
|
||||
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);
|
||||
AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" );
|
||||
AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" );
|
||||
fill_scheduled_response(&scheduled_response, dl_config, ul_config, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot);
|
||||
nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,20 +248,16 @@ int nr_ue_if_module_kill(uint32_t module_id) {
|
||||
|
||||
if (nr_ue_if_module_inst[module_id] != NULL){
|
||||
free(nr_ue_if_module_inst[module_id]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_ue_dcireq(nr_dcireq_t *dcireq) {
|
||||
|
||||
fapi_nr_dl_config_request_t *dl_config=&dcireq->dl_config_req;
|
||||
|
||||
fapi_nr_dl_config_request_t *dl_config = &dcireq->dl_config_req;
|
||||
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
|
||||
|
||||
dl_config->sfn=UE_mac->dl_config_request.sfn;
|
||||
dl_config->slot=UE_mac->dl_config_request.slot;
|
||||
dl_config->number_pdus=0;
|
||||
|
||||
//printf(" UE_mac->dl_config_request.slot %d VS dcireq->slot %d \n", UE_mac->dl_config_request.slot, dcireq->slot);
|
||||
dl_config->sfn = UE_mac->dl_config_request.sfn;
|
||||
dl_config->slot = UE_mac->dl_config_request.slot;
|
||||
|
||||
LOG_D(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot);
|
||||
|
||||
|
||||
@@ -399,9 +399,9 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(
|
||||
}
|
||||
|
||||
|
||||
for(i=0; i<buffer_len; ++i){
|
||||
printf("[RRC] MIB PDU : %d\n", bufferP[i]);
|
||||
}
|
||||
//for(i=0; i<buffer_len; ++i){
|
||||
// printf("[RRC] MIB PDU : %d\n", bufferP[i]);
|
||||
//}
|
||||
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||
&asn_DEF_NR_BCCH_BCH_Message,
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
#ifndef AES_H
|
||||
#define AES_H
|
||||
|
||||
// Implemented from Wikipedia description and OpenAir HSS
|
||||
|
||||
/*--------------------- Rijndael S box table ----------------------*/
|
||||
static const uint8_t S[256] = {
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
||||
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
||||
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
||||
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
||||
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
||||
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
||||
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
||||
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
||||
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
||||
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
||||
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
||||
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
||||
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
||||
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
||||
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
||||
};
|
||||
/*------- This array does the multiplication by x in GF(2^8) ------*/
|
||||
static const uint8_t Xtime[256] = {
|
||||
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
|
||||
32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
|
||||
64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94,
|
||||
96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126,
|
||||
128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158,
|
||||
160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190,
|
||||
192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222,
|
||||
224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254,
|
||||
27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5,
|
||||
59, 57, 63, 61, 51, 49, 55, 53, 43, 41, 47, 45, 35, 33, 39, 37,
|
||||
91, 89, 95, 93, 83, 81, 87, 85, 75, 73, 79, 77, 67, 65, 71, 69,
|
||||
123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109, 99, 97, 103, 101,
|
||||
155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133,
|
||||
187, 185, 191, 189, 179, 177, 183, 181, 171, 169, 175, 173, 163, 161, 167, 165,
|
||||
219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197,
|
||||
251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
Rijndael key schedule function. Takes 16-byte key and creates
|
||||
all Rijndael's internal subkeys ready for encryption.
|
||||
-----------------------------------------------------------------*/
|
||||
static inline void RijndaelKeySchedule (const uint8_t key[16], uint8_t roundKeys[11][4][4]) {
|
||||
//first round key equals key
|
||||
for (int i = 0; i < 16; i++)
|
||||
roundKeys[0][i & 0x03][i >> 2] = key[i];
|
||||
|
||||
//now calculate round keys
|
||||
uint8_t roundConst = 1;
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int next=i+1;
|
||||
roundKeys[next][0][0] = S[roundKeys[i][1][3]]
|
||||
^ roundKeys[i][0][0] ^ roundConst;
|
||||
roundKeys[next][1][0] = S[roundKeys[i][2][3]]
|
||||
^ roundKeys[i][1][0];
|
||||
roundKeys[next][2][0] = S[roundKeys[i][3][3]]
|
||||
^ roundKeys[i][2][0];
|
||||
roundKeys[next][3][0] = S[roundKeys[i][0][3]]
|
||||
^ roundKeys[i][3][0];
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
roundKeys[next][j][1] = roundKeys[i][j][1] ^ roundKeys[next][j][0];
|
||||
roundKeys[next][j][2] = roundKeys[i][j][2] ^ roundKeys[next][j][1];
|
||||
roundKeys[next][j][3] = roundKeys[i][j][3] ^ roundKeys[next][j][2];
|
||||
}
|
||||
|
||||
roundConst = Xtime[roundConst];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Round key addition function */
|
||||
static inline void KeyAdd (uint8_t state[4][4], uint8_t roundKeys[11][4][4], int round) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
state[i][j] ^= roundKeys[round][i][j];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Byte substitution transformation */
|
||||
static inline void ByteSub (uint8_t state[4][4]) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int j = 0; j < 4; j++)
|
||||
state[i][j] = S[state[i][j]];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Row shift transformation */
|
||||
static inline void ShiftRow (uint8_t state[4][4]) {
|
||||
// left rotate row 1 by 1
|
||||
uint8_t temp = state[1][0];
|
||||
state[1][0] = state[1][1];
|
||||
state[1][1] = state[1][2];
|
||||
state[1][2] = state[1][3];
|
||||
state[1][3] = temp;
|
||||
//left rotate row 2 by 2
|
||||
temp = state[2][0];
|
||||
state[2][0] = state[2][2];
|
||||
state[2][2] = temp;
|
||||
temp = state[2][1];
|
||||
state[2][1] = state[2][3];
|
||||
state[2][3] = temp;
|
||||
// left rotate row 3 by 3
|
||||
temp = state[3][0];
|
||||
state[3][0] = state[3][3];
|
||||
state[3][3] = state[3][2];
|
||||
state[3][2] = state[3][1];
|
||||
state[3][1] = temp;
|
||||
return;
|
||||
}
|
||||
|
||||
/* MixColumn transformation*/
|
||||
static inline void MixColumn ( uint8_t state[4][4]) {
|
||||
// do one column at a time
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint8_t temp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i];
|
||||
uint8_t tmp0 = state[0][i];
|
||||
// Xtime array does multiply by x in GF2^8
|
||||
uint8_t tmp = Xtime[state[0][i] ^ state[1][i]];
|
||||
state[0][i] ^= temp ^ tmp;
|
||||
tmp = Xtime[state[1][i] ^ state[2][i]];
|
||||
state[1][i] ^= temp ^ tmp;
|
||||
tmp = Xtime[state[2][i] ^ state[3][i]];
|
||||
state[2][i] ^= temp ^ tmp;
|
||||
tmp = Xtime[state[3][i] ^ tmp0];
|
||||
state[3][i] ^= temp ^ tmp;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
Rijndael encryption function. Takes 16-byte input and creates
|
||||
16-byte output (using round keys already derived from 16-byte
|
||||
key).
|
||||
-----------------------------------------------------------------*/
|
||||
static inline void RijndaelEncrypt ( const uint8_t input[16], uint8_t output[16], uint8_t roundKeys[11][4][4]) {
|
||||
uint8_t state[4][4];
|
||||
int r;
|
||||
|
||||
// initialise state array from input byte string
|
||||
for (int i = 0; i < 16; i++)
|
||||
state[i & 0x3][i >> 2] = input[i];
|
||||
|
||||
// add first round_key
|
||||
KeyAdd (state, roundKeys, 0);
|
||||
|
||||
// do lots of full rounds
|
||||
for (r = 1; r <= 9; r++) {
|
||||
ByteSub (state);
|
||||
ShiftRow (state);
|
||||
MixColumn (state);
|
||||
KeyAdd (state, roundKeys, r);
|
||||
}
|
||||
|
||||
// final round
|
||||
ByteSub (state);
|
||||
ShiftRow (state);
|
||||
KeyAdd (state, roundKeys, r);
|
||||
|
||||
// produce output byte string from state array
|
||||
for (int i = 0; i < 16; i++)
|
||||
output[i] = state[i & 0x3][i >> 2];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void aes_128_encrypt_block(const uint8_t *key, const uint8_t *clear, uint8_t *cyphered) {
|
||||
uint8_t roundKeys[11][4][4];
|
||||
RijndaelKeySchedule(key, roundKeys);
|
||||
RijndaelEncrypt (clear, cyphered, roundKeys);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
#ifndef MILENAGE_H
|
||||
#define MILENAGE_H
|
||||
#include <openair3/NAS/COMMON/aes.h>
|
||||
#include <openssl/aes.h>
|
||||
|
||||
|
||||
#define u8 uint8_t
|
||||
/**
|
||||
@@ -41,6 +42,14 @@
|
||||
@mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL
|
||||
Returns: true on success, false on failure
|
||||
*/
|
||||
|
||||
void aes_128_encrypt_block(const u8* key, const u8* in, u8* out) {
|
||||
AES_KEY k;
|
||||
u8 tmp[16];
|
||||
AES_set_encrypt_key(key, 128, &k);
|
||||
AES_encrypt(in, tmp, &k);
|
||||
memcpy(out, tmp, sizeof(tmp));
|
||||
}
|
||||
static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s) {
|
||||
u8 tmp1[16], tmp2[16], tmp3[16];
|
||||
@@ -51,6 +60,10 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
|
||||
tmp1[i] = _rand[i] ^ opc[i];
|
||||
|
||||
aes_128_encrypt_block(k, tmp1, tmp1);
|
||||
AES_KEY kTab;
|
||||
uint8_t cyphered[16];
|
||||
AES_set_encrypt_key(k, 128, &kTab);
|
||||
AES_encrypt(tmp1, cyphered, &kTab);
|
||||
/* tmp2 = IN1 = SQN || AMF || SQN || AMF */
|
||||
memcpy(tmp2, sqn, 6);
|
||||
memcpy(tmp2 + 6, amf, 2);
|
||||
|
||||
@@ -1736,7 +1736,7 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as
|
||||
uint32_t stream,
|
||||
S1AP_S1AP_PDU_t *pdu){
|
||||
|
||||
LOG_W(S1AP, "Implementation of S1AP E-RAB Modification confirm handler is pending...\n");
|
||||
LOG_I(S1AP, "Received S1AP E-RAB Modification confirm message \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user