diff --git a/.gitignore b/.gitignore index 06a51f1b64..73e0407c4b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # log and exec file cmake_targets/log/ cmake_targets/*/build/ +cmake_targets/ran_build/ log/ lte_build_oai/ -targets/bin/ \ No newline at end of file +targets/bin/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..6757ed47f6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/path/to/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 2f736c5dbd..d16de8b7ab 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -44,7 +44,7 @@ pipeline { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-Mono-FDD-Band13-X2-HO", "Test-TDD-Band78-gNB-NR-UE"]) + gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-IF4p5-TDD-Band38-Multi-RRU" , "Test-Mono-FDD-Band13-X2-HO", "Test-TDD-Band78-gNB-NR-UE"]) ansiColor('xterm') } @@ -57,6 +57,9 @@ pipeline { echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' def allParametersPresent = true + if (env.TESTPLATFORM_OWNER) { + echo "Platform is ${env.TESTPLATFORM_OWNER}" + } if (params.RedHatRemoteServer == null) { allParametersPresent = false @@ -128,8 +131,8 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] ]) { sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1" + sh "git checkout develop >> ../git_clone.log 2>&1" } - sh "sed -i -e 's#add-apt-repository.*cleishm.*neo4j#add-apt-repository ppa:cleishm/neo4j -y#' -e 's#libneo4j-client-dev#libneo4j-client-dev -y#' tools/install_dependencies" sh "zip -r -qq flexran.zip ." } } @@ -362,7 +365,7 @@ pipeline { stage ("Test physical simulators") { steps { script { - timeout (time: 45, unit: 'MINUTES') { + timeout (time: 90, unit: 'MINUTES') { try { gitlabCommitStatus(name: "Test phy-sim") { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" @@ -575,6 +578,25 @@ pipeline { } } } + stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") { + steps { + script { + triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210', 'Test-IF4p5-TDD-Band38-Multi-RRU') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } stage ("Test OAI UE - FDD - Band 20 - B200") { steps { script { diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index ae6b48cd51..72fa29aa39 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -44,7 +44,7 @@ function build_on_vm { STATUS=1 return fi - if [ ! -f /etc/apt/apt.conf.d/01proxy ] + if [[ ! -f /etc/apt/apt.conf.d/01proxy ]] && [[ "$OPTIONAL_APTCACHER" != "true" ]] then echo "Missing /etc/apt/apt.conf.d/01proxy file!" echo "Is apt-cacher installed and configured?" @@ -68,11 +68,12 @@ function build_on_vm { then echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_CPU = $VM_CPU" + echo "VM_DISK = $VM_DISK GBytes" echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure @@ -96,12 +97,12 @@ function build_on_vm { else scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu fi - scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu + [ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu echo "############################################################" echo "Running install and build script on VM ($VM_NAME)" echo "############################################################" - echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS + echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS echo "git config --global https.postBuffer 123289600" >> $VM_CMDS if [[ "$VM_NAME" == *"-cppcheck"* ]] @@ -179,8 +180,12 @@ function build_on_vm { echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS + echo "echo \"mkdir build\"" >> $VM_CMDS + echo "mkdir build" >> $VM_CMDS + echo "echo \"cd build\"" >> $VM_CMDS + echo "cd build" >> $VM_CMDS echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS - echo "$BUILD_OPTIONS > cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS + echo "$BUILD_OPTIONS > ../cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS fi if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] then diff --git a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf index eff8b68857..ab89d13193 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf @@ -233,6 +233,7 @@ eNBs = #pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2 pusch_maxNumRepetitionCEmodeA_r13 = "r8"; #0 + pusch_repetitionLevelCEmodeA_r13 = "l1"; #pusch_maxNumRepetitionCEmodeB_r13 = "r768"; #4 #NULL #pusch_HoppingOffset_v1310 = 5; #NULL diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index e0e1da4236..237a1a5d5e 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -85,12 +85,13 @@ function create_vm { echo "VM_NAME = $VM_NAME" echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_CPU = $VM_CPU" + echo "VM_DISK = $VM_DISK GBytes" echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 5a86702cc2..35574512f1 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -128,6 +128,7 @@ class SSHConnection(): self.Build_eNB_args = '' self.backgroundBuild = False self.backgroundBuildTestId = ['', '', ''] + self.Build_eNB_forced_workspace_cleanup = False self.Initialize_eNB_args = '' self.air_interface = 'lte' self.eNB_instance = '' @@ -370,9 +371,16 @@ class SSHConnection(): self.air_interface = 'nr' else: self.air_interface = 'lte' + if self.Build_eNB_forced_workspace_cleanup: + self.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) + result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) + if result is not None: + full_ran_repo_name = self.ranRepository + else: + full_ran_repo_name = self.ranRepository + '.git' self.command('mkdir -p ' + lSourcePath, '\$', 5) self.command('cd ' + lSourcePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # Raphael: here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) @@ -537,13 +545,42 @@ class SSHConnection(): ue_prefix = '' self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) self.command('cd ' + self.UESourceCodePath, '\$', 5) - self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) # here add a check if git clone or git fetch went smoothly self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5) if self.clean_repository: - pass + self.command('ls *.txt', '\$', 5) + result = re.search('LAST_BUILD_INFO', str(self.ssh.before)) + if result is not None: + mismatch = False + self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) + result = re.search(self.ranCommitID, str(self.ssh.before)) + if result is None: + mismatch = True + self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) + if (self.ranAllowMerge): + result = re.search('YES', str(self.ssh.before)) + if result is None: + mismatch = True + self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) + if self.ranTargetBranch == '': + result = re.search('develop', str(self.ssh.before)) + else: + result = re.search(self.ranTargetBranch, str(self.ssh.before)) + if result is None: + mismatch = True + else: + result = re.search('NO', str(self.ssh.before)) + if result is None: + mismatch = True + if not mismatch: + self.close() + self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) + return + self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) + # if the commit ID is provided use it to point to it if self.ranCommitID != '': self.command('git checkout -f ' + self.ranCommitID, '\$', 5) @@ -571,12 +608,23 @@ class SSHConnection(): self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) - self.close() if buildStatus: - logging.info('\u001B[1m Building OAI ' + ue_prefix + 'UE Pass\u001B[0m') + # Generating a BUILD INFO file + self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) + self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + if (self.ranAllowMerge): + self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) + if self.ranTargetBranch == '': + self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) + else: + self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + else: + self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) + self.close() self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') else: - logging.error('\u001B[1m Building OAI ' + ue_prefix + 'UE Failed\u001B[0m') + self.close() + logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE') self.CreateHtmlTabFooter(False) sys.exit(1) @@ -738,13 +786,13 @@ class SSHConnection(): # do not reset board twice in IF4.5 case result = re.search('^rru|^enb|^du.band', str(config_file)) if result is not None: - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 10) + self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 30) result = re.search('type: b200', str(self.ssh.before)) if result is not None: logging.debug('Found a B2xx device --> resetting it') self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) # Reloading FGPA bin firmware - self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 15) + self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 30) # Make a copy and adapt to EPC / eNB IP addresses self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); @@ -1138,7 +1186,7 @@ class SSHConnection(): html_queue = SimpleQueue() self.checkDevTTYisUnlocked() if attach_status: - html_cell = '
CAT-M module\nAttachment Completed in ' + str(attach_cnt+4) + ' seconds'
+			html_cell = '
CAT-M module Attachment Completed in ' + str(attach_cnt+4) + ' seconds'
 			if (nRSRQ is not None) and (nRSRP is not None):
 				html_cell += '\n   RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB'
 				html_cell += '\n   RSRP = ' + str(-140+nRSRP) + ' dBm
' @@ -1147,9 +1195,11 @@ class SSHConnection(): html_queue.put(html_cell) self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) else: - html_cell = '
CAT-M module\nAttachment Failed
' + logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') + html_cell = '
CAT-M module Attachment Failed
' html_queue.put(html_cell) self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) + self.AutoTerminateUEandeNB() def PingCatM(self): if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': @@ -1160,7 +1210,7 @@ class SSHConnection(): pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.prematureExit = True + self.AutoTerminateUEandeNB() return try: statusQueue = SimpleQueue() @@ -1179,6 +1229,8 @@ class SSHConnection(): if result is not None: moduleIPAddr = result.group('ipaddr') else: + self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() return ping_time = re.findall("-c (\d+)",str(self.ping_args)) device_id = 'catm' @@ -2409,15 +2461,16 @@ class SSHConnection(): os.kill(os.getppid(),signal.SIGUSR1) def IperfNoS1(self): + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + Usage() + sys.exit('Insufficient Parameter') check_eNB = True check_OAI_UE = True pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.AutoTerminateUEandeNB() - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - Usage() - sys.exit('Insufficient Parameter') + return server_on_enb = re.search('-R', str(self.iperf_args)) if server_on_enb is not None: iServerIPAddr = self.eNBIPAddress @@ -3447,6 +3500,11 @@ class SSHConnection(): self.ShowTestID() self.eNB_instance = '0' self.TerminateeNB() + if self.flexranCtrlInstalled and self.flexranCtrlStarted: + self.testCase_id = 'AUTO-KILL-flexran-ctl' + self.desc = 'Automatic Termination of FlexRan CTL' + self.ShowTestID() + self.TerminateFlexranCtrl() self.prematureExit = True def IdleSleep(self): @@ -3716,7 +3774,7 @@ class SSHConnection(): if result is not None: self.UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + self.UhdVersion) - self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 12) + self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 30) usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before)) count = 0 for board in usrp_boards: @@ -4108,6 +4166,14 @@ def CheckClassValidity(action,id): def GetParametersFromXML(action): if action == 'Build_eNB': SSH.Build_eNB_args = test.findtext('Build_eNB_args') + forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') + if (forced_workspace_cleanup is None): + SSH.Build_eNB_forced_workspace_cleanup = False + else: + if re.match('true', forced_workspace_cleanup, re.IGNORECASE): + SSH.Build_eNB_forced_workspace_cleanup = True + else: + SSH.Build_eNB_forced_workspace_cleanup = False SSH.eNB_instance = test.findtext('eNB_instance') if (SSH.eNB_instance is None): SSH.eNB_instance = '0' @@ -4564,7 +4630,11 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re while cnt < SSH.repeatCounts[0] and SSH.prematureExit: SSH.prematureExit = False for test_case_id in todo_tests: + if SSH.prematureExit: + break for test in all_tests: + if SSH.prematureExit: + break id = test.get('id') if test_case_id != id: continue @@ -4645,10 +4715,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re SSH.Perform_X2_Handover() else: sys.exit('Invalid action') - if SSH.prematureExit: - break - if SSH.prematureExit: - break cnt += 1 if cnt == SSH.repeatCounts[0] and SSH.prematureExit: logging.debug('Testsuite failed ' + str(cnt) + ' time(s)') diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 7fba7bac79..9d6349077f 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -52,7 +52,7 @@ function variant_usage { if [ "$1" = "full" ] then printf " VM_NAME=%-15s ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC" - printf " VM_MEMORY=%-15s VM_CPU=%-15s\n" "$VM_MEMORY" "$VM_CPU" + printf " VM_MEMORY=%-15s VM_CPU=%-15s VM_DISK=%-15s\n" "$VM_MEMORY" "$VM_CPU" "$VM_DISK" printf " NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\"" printf " LOG_PATTERN=%-15s EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN" "$EXPERIMENTAL" fi @@ -140,10 +140,25 @@ function command_options_usage { echo "" } +# function to set specific behavior depending on the TESTPLATFORM_OWNER variable +# which may be set by a jenkins server for exemple +function platform_set { + if [ "$TESTPLATFORM_OWNER" != "" ] + then + echo "Running on $TESTPLATFORM_OWNER platform" + if [ -x "/usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh" ] + then + . /usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh + fi + fi +} + function setvar_usage { declare -A HELP_VAR HELP_VAR["VM_OSREL"]="OS release to use in virtual machines" HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\"" + HELP_VAR["OPTIONAL_APTCACHER"]="build and Run tests will fail if apt-cacher not installed and this variable not set to \"true\"" + HELP_VAR["TESTPLATFORM_OWNER"]="Allow pipeline customization via execution of an externel scripts residing on the jenkins server" echo "--setvar_ where varname is one of:" for i in ${AUTHORIZED_VAR[@]}; do printf "%20s : %s\n" "$i" "${HELP_VAR[$i]}" ;done } @@ -167,25 +182,30 @@ function variant__v2__basic_sim { } function variant__v3__phy_sim { - NB_PATTERN_FILES=12 + NB_PATTERN_FILES=13 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 - RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" + VM_DISK=20 + RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b" } function variant__v4__cppcheck { VM_MEMORY=4096 LOG_PATTERN=cppcheck.xml NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -I openair3/NAS/COMMON/UTIL -j4" + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 -i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -I openair3/NAS/COMMON/UTIL -j4" } function variant__v5__gnb_usrp { + VM_MEMORY=8192 + VM_CPU=8 NB_PATTERN_FILES=9 BUILD_OPTIONS="--gNB -w USRP" } function variant__v6__nr_ue_usrp { + VM_MEMORY=4096 + VM_CPU=4 NB_PATTERN_FILES=9 BUILD_OPTIONS="--nrUE -w USRP" } @@ -207,7 +227,7 @@ function variant__v8__ue_ethernet { function variant__v10__flexran_rtc { ARCHIVES_LOC=flexran NB_PATTERN_FILES=1 - BUILD_OPTIONS="cmake . && make -j2" + BUILD_OPTIONS="cmake .. && make -j2" VARIANT_INFO="non-OSA" } @@ -218,8 +238,8 @@ function variant__v20__l1_sim { } function variant__v21__rf_sim { + ARCHIVES_LOC=rf_sim RUN_OPTIONS="complex" - EXPERIMENTAL="true" } function variant__v22__l2_sim { @@ -257,6 +277,7 @@ function check_set_variant { ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"} VM_MEMORY=2048 VM_CPU=4 + VM_DISK=10 EXPERIMENTAL="" NBARGS=$[$NBARGS+$VARIANT_OPTID] variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"} @@ -328,6 +349,7 @@ function check_setvar { exit 1 } +platform_set MY_DIR=$(dirname $(readlink -f $0)) . $MY_DIR/createVM.sh . $MY_DIR/buildOnVM.sh @@ -337,6 +359,7 @@ MY_DIR=$(dirname $(readlink -f $0)) . $MY_DIR/reportBuildLocally.sh . $MY_DIR/reportTestLocally.sh + if [ $# -lt 1 ] then echo "Syntax Error: too few arguments" @@ -454,7 +477,7 @@ RUN_OPTIONS="none" # list of variables that can be set via the --setvar option -AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL") +AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER") #variables to set which OS VM should use @@ -477,6 +500,7 @@ AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL") # -V option. VM_NAME="" VM_MEMORY=0 +VM_DISK=0 VM_CPU=0 ARCHIVES_LOC="" LOG_PATTERN="" diff --git a/ci-scripts/rcc-files/rbconfig.raw b/ci-scripts/rcc-files/rbconfig.raw new file mode 100644 index 0000000000..9c561b7a9f --- /dev/null +++ b/ci-scripts/rcc-files/rbconfig.raw @@ -0,0 +1 @@ + (ׂÀ \ No newline at end of file diff --git a/ci-scripts/rcc-files/reconfig.raw b/ci-scripts/rcc-files/reconfig.raw new file mode 100644 index 0000000000..5c5e01afe2 Binary files /dev/null and b/ci-scripts/rcc-files/reconfig.raw differ diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index dd0e6b819c..e087cc04e6 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -97,14 +97,20 @@ function analyzeIperfFiles { FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` if [ $FILE_COMPLETE -eq 0 ] then - echo " KO" >> ./test_simulator_results.html SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` - EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` + EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}else{printf "%.2f KBits/sec", br/1000}}'` PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` + if [[ $PERF_INT -lt 80 ]] + then + echo " KO" >> ./test_simulator_results.html + else + echo " OK" >> ./test_simulator_results.html + fi else EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] @@ -394,6 +400,126 @@ function report_test { echo " " >> ./test_simulator_results.html fi + ARCHIVES_LOC=archives/rf_sim/test + if [ -d $ARCHIVES_LOC ] + then + echo "

5G NR RF Simulator Check

" >> ./test_simulator_results.html + + if [ -f $ARCHIVES_LOC/test_final_status.log ] + then + if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ] + then + echo "
" >> ./test_simulator_results.html + echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + else + echo "
" >> ./test_simulator_results.html + echo " TEST was a FAILURE! " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + fi + else + echo "
" >> ./test_simulator_results.html + echo " COULD NOT DETERMINE TEST FINAL STATUS! " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + fi + + echo " " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + + EPC_CONFIGS=("noS1") + TRANS_MODES=("tdd") + BW_CASES=(106) + for CN_CONFIG in ${EPC_CONFIGS[@]} + do + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + echo " " >> ./test_simulator_results.html + if [[ $CN_CONFIG =~ .*wS1.* ]] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + 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 ] + then + NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` + NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfuly configured" $ENB_LOG` + NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "Initial sync: starting PBCH detection" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfuly configured" $UE_LOG` + if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + #PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping*.log 2> /dev/null` + #analyzePingFiles + + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_iperf_dl*client*txt 2> /dev/null` + analyzeIperfFiles + + #IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul*client*txt 2> /dev/null` + #analyzeIperfFiles + done + done + done + + echo "
Log File NameCommandStatusStatistics
Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB
$NAME_ENB --- $NAME_UEN/AOKKO
" >> ./test_simulator_results.html
+                    if [ $NB_ENB_GOT_SYNC -gt 0 ]
+                    then
+                        echo "- gNB --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- gNB NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_ENB_TUNNEL_UP -gt 0 ]
+                    then
+                        echo "- gNB mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                    else
+                        echo "- gNB NEVER mounted oaitun_enb1 interface" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_UE_GOT_SYNC -gt 0 ]
+                    then
+                        echo "- NR UE --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
+                    then
+                        echo "- NR UE attached to gNB" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE NEVER attached to eNB" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_UE_TUNNEL_UP -gt 0 ]
+                    then
+                        echo "- NR UE mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                    else
+                        echo "- NR UE NEVER mounted oaitun_ue1 interface" >> ./test_simulator_results.html
+                    fi
+                    echo "        
" >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + fi + ARCHIVES_LOC=archives/l2_sim/test if [ -d $ARCHIVES_LOC ] then diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index e93f23120c..118c4b4d9e 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -274,21 +274,30 @@ function generic_iperf { local LOC_BASE_LOG_FILE=$8 local LOC_PORT_ID=$[$9+5001] local LOC_FG_OR_BG=${10} + # By default the requested bandwidth is in Mbits/sec + if [[ $LOC_REQ_BANDWIDTH =~ .*K.* ]] + then + local IPERF_FORMAT="-fk" + local FORMATTED_REQ_BW=$LOC_REQ_BANDWIDTH + else + local IPERF_FORMAT="-fm" + local FORMATTED_REQ_BW=${LOC_REQ_BANDWIDTH}"M" + fi # Starting Iperf Server - echo "iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID}" - echo "nohup iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID} > ${LOC_BASE_LOG_FILE}_server.txt 2>&1 &" > ${LOC_ISERVER_CMD} + echo "iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 ${IPERF_FORMAT} -p ${LOC_PORT_ID}" + echo "nohup iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 ${IPERF_FORMAT} -p ${LOC_PORT_ID} > ${LOC_BASE_LOG_FILE}_server.txt 2>&1 &" > ${LOC_ISERVER_CMD} ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ISERVER_IP} < ${LOC_ISERVER_CMD} rm ${LOC_ISERVER_CMD} # Starting Iperf Client - echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}" - echo "echo \"COMMAND IS: iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}\" > ${LOC_BASE_LOG_FILE}_client.txt" > ${LOC_ICLIENT_CMD} + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}" + echo "echo \"COMMAND IS: iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}\" > ${LOC_BASE_LOG_FILE}_client.txt" > ${LOC_ICLIENT_CMD} if [ $LOC_FG_OR_BG -eq 0 ] then - echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1" >> ${LOC_ICLIENT_CMD} + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1" >> ${LOC_ICLIENT_CMD} echo "tail -3 ${LOC_BASE_LOG_FILE}_client.txt | grep -v datagram" >> ${LOC_ICLIENT_CMD} else - echo "nohup iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1 &" >> ${LOC_ICLIENT_CMD} + echo "nohup iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${FORMATTED_REQ_BW} -i 1 ${IPERF_FORMAT} -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1 &" >> ${LOC_ICLIENT_CMD} fi ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ICLIENT_IP} < ${LOC_ICLIENT_CMD} rm -f ${LOC_ICLIENT_CMD} @@ -305,19 +314,46 @@ function generic_iperf { function check_iperf { local LOC_BASE_LOG=$1 - local LOC_REQ_BW=$2 + local LOC_REQ_BW=`echo $2 | sed -e "s#K##"` local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l` local LOC_REQ_BW_MINUS_TWO=`echo "$LOC_REQ_BW - 2" | bc -l` local LOC_REQ_BW_MINUS_THREE=`echo "$LOC_REQ_BW - 3" | bc -l` local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` + local LOC_IS_RF_SIM=`echo $LOC_BASE_LOG | grep -c rf_sim` + local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c tdd_106prb` if [ -f ${LOC_BASE_LOG}_client.txt ] then local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` if [ $FILE_COMPLETE -eq 0 ] then - IPERF_STATUS=-1 - echo "File Report not found" + if [[ $LOC_IS_RF_SIM -eq 1 ]] && [[ $LOC_IS_NR -eq 1 ]] + then + echo "no UL integration right now --> normal to have no server report" + if [ -f ${LOC_BASE_LOG}_server.txt ] + then + local EFFECTIVE_BANDWIDTH=`tail -n1 ${LOC_BASE_LOG}_server.txt | sed -e "s#^.*MBytes *##" -e "s#^.*KBytes *##" -e "s#sec.*#sec#"` + if [[ $2 =~ .*K.* ]] + then + local BW_SUFFIX="K" + else + local BW_SUFFIX="M" + fi + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*${BW_SUFFIX}bits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*${BW_SUFFIX}bits.* ]] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + echo "got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + IPERF_STATUS=-1 + fi + else + IPERF_STATUS=-1 + echo "Server File Report not found" + fi + else + IPERF_STATUS=-1 + echo "File Report not found" + fi else local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ] @@ -351,40 +387,26 @@ function check_iperf { } function terminate_enb_ue_basic_sim { - # mode = 0 : eNB + UE - # mode = 1 : eNB - # mode = 2 : UE + # mode = 0 : eNB + UE or gNB and NR-UE + # mode = 1 : eNB or gNB + # mode = 2 : UE or NR-UE local LOC_MODE=$3 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" > $1 if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=enb_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=enb_daemon --stop; fi" >> $1 - fi - if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] - then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=ue_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=ue_daemon --stop; fi" >> $1 - fi - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 - echo "echo \"ps -aux | grep softmodem\"" >> $1 - echo "ps -aux | grep softmodem | grep -v grep" >> $1 - echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] - then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGINT lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGINT lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGINT .*-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGINT .*-softmodem; fi" >> $1 echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 echo "echo \"ps -aux | grep softmodem\"" >> $1 echo "ps -aux | grep softmodem | grep -v grep" >> $1 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGKILL .*-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGKILL .*-softmodem; fi" >> $1 fi if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] then - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-uesoftmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-uesoftmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall -r --signal SIGKILL .*-uesoftmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall -r --signal SIGKILL .*-uesoftmodem; fi" >> $1 echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 fi echo "echo \"ps -aux | grep softmodem\"" >> $1 @@ -476,7 +498,7 @@ function install_epc_on_vm { local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME` echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR" - scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu + [ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu # ltebox specific actions (install and start) LTE_BOX_TO_INSTALL=1 @@ -500,7 +522,7 @@ function install_epc_on_vm { echo "############################################################" echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)" echo "############################################################" - echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS + echo "sudo [ -f 01proxy ] && cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS @@ -1075,6 +1097,162 @@ function start_rf_sim_ue { } +function start_rf_sim_gnb { + local LOC_GNB_VM_IP_ADDR=$2 + local LOC_LOG_FILE=$3 + local LOC_NB_RBS=$4 + local LOC_CONF_FILE=$5 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$6 + echo "cd /home/ubuntu/tmp" > $1 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"source oaienv\"" >> $1 + echo "source oaienv" >> $1 + echo "cd ci-scripts/conf_files/" >> $1 + echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 + #echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_ENB_VM_IP_ADDR#' -e 's#CI_UE_IP_ADDR#$LOC_UE_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + #echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 + #echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $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 + fi + echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 + echo "cat ./my-nr-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=gnb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/ran_build/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-nr-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"got sync\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + GNB_SYNC=0 + echo "RF-SIM gNB is NOT sync'ed: process still alive?" + else + GNB_SYNC=1 + echo "RF-SIM gNB is sync'ed: waiting for UE(s) to connect" + fi + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1 + # Checking oaitun_enb1 interface has now an IP address + i="0" + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_GNB_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + sleep 5 + fi + done + rm $1 + if [ $i -lt 50 ] + then + GNB_SYNC=0 + echo "RF-SIM gNB oaitun_enb1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM gNB oaitun_enb1 is UP and CONFIGURED" + fi + fi + sleep 10 +} + +function start_rf_sim_nr_ue { + local LOC_NR_UE_VM_IP_ADDR=$2 + local LOC_GNB_VM_IP_ADDR=$3 + local LOC_LOG_FILE=$4 + local LOC_PRB=$5 + local LOC_FREQUENCY=$6 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$7 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 + echo "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 --numerology 1 -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --phy-test --rcc_config_path /home/ubuntu/tmp/ci-scripts/rcc-files --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + fi + echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 + echo "cat ./my-nr-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=nr_ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/ran_build/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-nr-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"rfsimulator: Success\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + NR_UE_SYNC=1 + rm $1 + if [ $i -lt 50 ] + then + NR_UE_SYNC=0 + echo "RF-SIM NR-UE is NOT sync'ed w/ gNB" + return + else + echo "RF-SIM NR-UE is sync'ed w/ gNB" + fi + # Checking oaitun_ue1 interface has now an IP address + i="0" + echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + NR_UE_SYNC=0 + echo "RF-SIM NR-UE oaitun_ue1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM NR-UE oaitun_ue1 is UP and CONFIGURED" + fi + sleep 10 +} + + function run_test_on_vm { echo "############################################################" echo "OAI CI VM script" @@ -1089,6 +1267,14 @@ function run_test_on_vm { UE_VM_CMDS=${UE_VM_NAME}_cmds.txt echo "UE_VM_NAME = $UE_VM_NAME" echo "UE_VM_CMD_FILE = $UE_VM_CMDS" + GNB_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#gnb-usrp#" -e "s#rf-sim#gnb-usrp#"` + GNB_VM_CMDS=${GNB_VM_NAME}_cmds.txt + echo "GNB_VM_NAME = $GNB_VM_NAME" + echo "GNB_VM_CMD_FILE = $GNB_VM_CMDS" + NR_UE_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#nr-ue-usrp#" -e "s#rf-sim#nr-ue-usrp#"` + NR_UE_VM_CMDS=${UE_VM_NAME}_cmds.txt + echo "NR_UE_VM_NAME = $NR_UE_VM_NAME" + echo "NR_UE_VM_CMD_FILE = $NR_UE_VM_CMDS" else echo "VM_NAME = $VM_NAME" echo "VM_CMD_FILE = $VM_CMDS" @@ -1113,6 +1299,22 @@ function run_test_on_vm { UE_VM_IP_ADDR=`uvt-kvm ip $UE_VM_NAME` echo "$UE_VM_NAME has for IP addr = $UE_VM_IP_ADDR" + + echo "############################################################" + echo "Waiting for GNB VM to be started" + echo "############################################################" + uvt-kvm wait $GNB_VM_NAME --insecure + + GNB_VM_IP_ADDR=`uvt-kvm ip $GNB_VM_NAME` + echo "$GNB_VM_NAME has for IP addr = $GNB_VM_IP_ADDR" + + echo "############################################################" + echo "Waiting for NR-UE VM to be started" + echo "############################################################" + uvt-kvm wait $NR_UE_VM_NAME --insecure + + NR_UE_VM_IP_ADDR=`uvt-kvm ip $NR_UE_VM_NAME` + echo "$NR_UE_VM_NAME has for IP addr = $NR_UE_VM_IP_ADDR" else echo "############################################################" echo "Waiting for VM to be started" @@ -1149,6 +1351,11 @@ function run_test_on_vm { echo "cp /home/ubuntu/bc-install.txt log" >> $VM_CMDS echo "cd log" >> $VM_CMDS echo "zip -r -qq tmp.zip *.* 0*" >> $VM_CMDS + echo "echo \"############################################################\"" >> $VM_CMDS + echo "echo \"Evaluating remaining memory on disk!\"" >> $VM_CMDS + echo "echo \"############################################################\"" >> $VM_CMDS + echo "echo \"df -h\"" >> $VM_CMDS + echo "df -h" >> $VM_CMDS ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS @@ -1461,7 +1668,7 @@ function run_test_on_vm { fi fi - if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-ru-sim.* ]] then PING_STATUS=0 IPERF_STATUS=0 @@ -1661,6 +1868,84 @@ function run_test_on_vm { fi fi + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] + then + PING_STATUS=0 + IPERF_STATUS=0 + if [ -d $ARCHIVES_LOC ] + then + rm -Rf $ARCHIVES_LOC + fi + mkdir --parents $ARCHIVES_LOC + + CN_CONFIG="noS1" + CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf + S1_NOS1_CFG=0 + PRB=106 + FREQUENCY=3510 + + ######### start of loop + + 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 + + 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 + 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 + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + STATUS=-1 + return + fi + + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + THROUGHPUT="30K" + CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl + get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR + get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1 + generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT + + echo "############################################################" + echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators" + echo "############################################################" + 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 + + ######### end of loop + full_l2_sim_destroy + + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $STATUS -eq 0 ] + then + echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + else + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + fi + fi + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-l2-sim.* ]] then PING_STATUS=0 diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 9626e36551..f066dacd81 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -76,6 +76,8 @@ function wait_on_vm_build { echo "echo \"ps -aux | grep build \"" >> $VM_CMDS echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS fi + echo "echo \"df -h\"" >> $VM_CMDS + echo "df -h" >> $VM_CMDS ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS rm -f $VM_CMDS diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml index aac71198f1..4dbfe00821 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml @@ -25,10 +25,23 @@ EPC-Start log-in + 010101 090101 050101 060101 070101 + + Build_eNB + Build eNB (USRP) + -w USRP -c --eNB + + + + Build_OAI_UE + Build OAI UE + -w USRP --UE + + Initialize_HSS Initialize HSS diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml index a2e74c6de9..3eca883aa6 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -24,7 +24,7 @@ test-05-tm1-nos1-tunnel Test-05MHz-TM1-noS1-tunnel tasks - 2 + 4 030201 090109 030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201 diff --git a/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml b/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml index 07fb6951f8..e52faa7a31 100644 --- a/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml +++ b/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml @@ -25,10 +25,16 @@ EPC-Closure log-out + 040202 050201 060201 070201 + + Terminate_CatM_module + Terminate CAT-M Module + + Terminate_HSS Terminate HSS diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml index 1b57c077ba..bba92930c5 100644 --- a/ci-scripts/xml_files/gnb_usrp_build.xml +++ b/ci-scripts/xml_files/gnb_usrp_build.xml @@ -34,6 +34,7 @@ Build_eNB Build gNB (USRP) --gNB -w USRP + True diff --git a/ci-scripts/xml_files/simple_dummy_build.xml b/ci-scripts/xml_files/simple_dummy_build.xml new file mode 100644 index 0000000000..75e5f6339a --- /dev/null +++ b/ci-scripts/xml_files/simple_dummy_build.xml @@ -0,0 +1,41 @@ + + + build-tab + Build + wrench + + 010101 + + + + + + Build_eNB + Build Master eNB (USRP) + -w USRP -c --eNB + 0 + 0 + + + diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml index 91280462b7..f8aaafd9a0 100644 --- a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml @@ -26,6 +26,7 @@ tasks 030201 030202 + 050202 @@ -43,4 +44,9 @@ 1 + + Terminate_FlexranCtrl + Stopping Flexran Controller + + diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 426c8cd9fd..f5bec7637c 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -185,7 +185,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU # set a flag for changes in the source code # these changes are related to hardcoded path to include .h files set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O3") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2") set(GIT_BRANCH "UNKNOWN") @@ -530,6 +530,7 @@ set (SHLIB_LOADER_SOURCES include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/") set(HWLIB_USRP_SOURCE ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp + ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib_config.c ) add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} ) target_link_libraries(oai_usrpdevif uhd) @@ -1204,7 +1205,6 @@ set(PHY_SRC_COMMON ${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c ${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c ${OPENAIR1_DIR}/PHY/CODING/nr_segmentation.c - ${OPENAIR1_DIR}/PHY/CODING/nr_compute_tbs.c ${OPENAIR1_DIR}/PHY/CODING/nr_rate_matching.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c @@ -1319,6 +1319,7 @@ set(PHY_SRC_UE set(PHY_NR_SRC_COMMON ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools_common.c ) set(PHY_NR_SRC @@ -1340,7 +1341,11 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c + ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c + ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c + ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c + ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c #${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c @@ -1386,6 +1391,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c + ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -1478,15 +1484,8 @@ set(RRC_DIR ${OPENAIR2_DIR}/RRC/LTE) set(NR_RRC_DIR ${OPENAIR2_DIR}/RRC/NR) set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE) set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0) -set(L2_SRC - ${OPENAIR2_DIR}/LAYER2/openair2_proc.c - ${PDCP_DIR}/pdcp.c - ${PDCP_DIR}/pdcp_fifo.c - ${PDCP_DIR}/pdcp_sequence_manager.c - ${PDCP_DIR}/pdcp_primitives.c - ${PDCP_DIR}/pdcp_util.c - ${PDCP_DIR}/pdcp_security.c - ${PDCP_DIR}/pdcp_netlink.c + +set(LTE_RLC_SRC ${RLC_AM_DIR}/rlc_am.c ${RLC_AM_DIR}/rlc_am_init.c ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c @@ -1514,6 +1513,29 @@ set(L2_SRC ${RLC_DIR}/rlc.c ${RLC_DIR}/rlc_rrc.c ${RLC_DIR}/rlc_mpls.c + ) + +set(NR_RLC_SRC + ${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_am.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_tm.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_um.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_oai_api.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_pdu.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c + ) + +set(L2_SRC + ${OPENAIR2_DIR}/LAYER2/openair2_proc.c + ${PDCP_DIR}/pdcp.c + ${PDCP_DIR}/pdcp_fifo.c + ${PDCP_DIR}/pdcp_sequence_manager.c + ${PDCP_DIR}/pdcp_primitives.c + ${PDCP_DIR}/pdcp_util.c + ${PDCP_DIR}/pdcp_security.c + ${PDCP_DIR}/pdcp_netlink.c # ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_endc.c @@ -1525,7 +1547,12 @@ set(L2_SRC ${RRC_DIR}/L2_interface_ue.c ) +set(L2_LTE_SRC + ${LTE_RLC_SRC} + ) + set(L2_NR_SRC + ${NR_RLC_SRC} ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c @@ -1544,40 +1571,25 @@ set(L2_SRC_UE ${PDCP_DIR}/pdcp_util.c ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c - ${RLC_AM_DIR}/rlc_am.c - ${RLC_AM_DIR}/rlc_am_init.c - ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c - ${RLC_AM_DIR}/rlc_am_timer_reordering.c - ${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c - ${RLC_AM_DIR}/rlc_am_segment.c - ${RLC_AM_DIR}/rlc_am_segments_holes.c - ${RLC_AM_DIR}/rlc_am_in_sdu.c - ${RLC_AM_DIR}/rlc_am_receiver.c - ${RLC_AM_DIR}/rlc_am_retransmit.c - ${RLC_AM_DIR}/rlc_am_windows.c - ${RLC_AM_DIR}/rlc_am_rx_list.c - ${RLC_AM_DIR}/rlc_am_reassembly.c - ${RLC_AM_DIR}/rlc_am_status_report.c - ${RLC_TM_DIR}/rlc_tm.c - ${RLC_TM_DIR}/rlc_tm_init.c - ${RLC_UM_DIR}/rlc_um.c - ${RLC_UM_DIR}/rlc_um_fsm.c - ${RLC_UM_DIR}/rlc_um_control_primitives.c - ${RLC_UM_DIR}/rlc_um_segment.c - ${RLC_UM_DIR}/rlc_um_reassembly.c - ${RLC_UM_DIR}/rlc_um_receiver.c - ${RLC_UM_DIR}/rlc_um_dar.c - ${RLC_DIR}/rlc_mac.c - ${RLC_DIR}/rlc.c - ${RLC_DIR}/rlc_rrc.c - ${RLC_DIR}/rlc_mpls.c ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface_common.c ${RRC_DIR}/L2_interface_ue.c ) + +set(LTE_NR_L2_SRC_UE + ${PDCP_DIR}/pdcp.c + ${PDCP_DIR}/pdcp_fifo.c + ${PDCP_DIR}/pdcp_sequence_manager.c + ${PDCP_DIR}/pdcp_primitives.c + ${PDCP_DIR}/pdcp_util.c + ${PDCP_DIR}/pdcp_security.c + ${PDCP_DIR}/pdcp_netlink.c + ${LTE_RLC_SRC} + ) set(NR_L2_SRC_UE + ${NR_RLC_SRC} ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c @@ -1628,13 +1640,14 @@ set (MAC_SRC_UE ${MAC_DIR}/config_ue.c ) - + set (MAC_NR_SRC_UE ${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c ${NR_UE_MAC_DIR}/config_ue.c ${NR_UE_MAC_DIR}/mac_vars.c ${NR_UE_MAC_DIR}/main_ue_nr.c ${NR_UE_MAC_DIR}/nr_ue_procedures.c + ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c ) set (ENB_APP_SRC @@ -1665,6 +1678,10 @@ add_library(MAC_UE_NR ${MAC_NR_SRC_UE} ) +add_library(L2_LTE + ${L2_LTE_SRC} + ) + add_library(L2_NR ${L2_NR_SRC} ${MAC_NR_SRC} @@ -1684,8 +1701,8 @@ endif() 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_gNB/nr_mac_common.c ) + +add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c) include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE") include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE") @@ -2038,7 +2055,7 @@ add_library(LFDS7 # Simulation library ########################## -add_library(SIMU +set (SIMUSRC ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c @@ -2049,9 +2066,13 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c ${OPENAIR1_DIR}/SIMULATION/RF/rf.c ${OPENAIR1_DIR}/SIMULATION/RF/dac.c ${OPENAIR1_DIR}/SIMULATION/RF/adc.c -${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c +${OPENAIR_DIR}/targets/ARCH/rfsimulator/apply_channelmod.c +#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ) +# Simulation library +########################## +add_library( SIMU SHARED ${SIMUSRC} ) add_library(SIMU_ETH ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -2267,6 +2288,10 @@ add_library(minimal_lib ) target_link_libraries(minimal_lib pthread dl ${T_LIB}) +add_executable(nfapi_test + ${OPENAIR_DIR}/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c + ) + add_executable(replay_node ${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c ) @@ -2309,7 +2334,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-softmodem -Wl,--start-group RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB - PHY_COMMON PHY PHY_RU LFDS L2 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 + PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -2357,7 +2382,6 @@ add_executable(lte-uesoftmodem ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c ${OPENAIR_TARGETS}/RT/USER/rfsim.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c @@ -2382,7 +2406,7 @@ endif() target_link_libraries (lte-uesoftmodem -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON - PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} + PHY_UE PHY_RU LFDS L2_UE L2_LTE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -2431,44 +2455,6 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRY target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) -# nr-softmodem-nos1 -################################################### - -add_executable(nr-softmodem-nos1 - ${rrc_h} - ${s1ap_h} -# ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_DIR}/executables/nr-gnb.c - ${OPENAIR_DIR}/executables/nr-ru.c - ${OPENAIR_DIR}/executables/nr-softmodem.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR2_DIR}/RRC/NAS/nas_config.c - ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR_DIR}/common/utils/utils.c - ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${GTPU_need_ITTI} - ${XFORMS_SOURCE_NR} - ${T_SOURCE} - ${CONFIG_SOURCES} - ${SHLIB_LOADER_SOURCES} - ) - -target_link_libraries (nr-softmodem-nos1 - -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA - ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - -Wl,--end-group z dl) - -target_link_libraries (nr-softmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-softmodem-nos1 ${T_LIB}) - # nr-uesoftmodem is UE implementation ####################################### @@ -2483,6 +2469,7 @@ add_executable(nr-uesoftmodem ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c @@ -2507,38 +2494,6 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${C target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) -# nr-uesoftmodem-nos1 -####################################### - -add_executable(nr-uesoftmodem-nos1 - ${rrc_h} - ${s1ap_h} -# ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_DIR}/executables/nr-ue.c - ${OPENAIR_DIR}/executables/nr-uesoftmodem.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR_DIR}/common/utils/utils.c - ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${XFORMS_SOURCE_NR} - ${T_SOURCE} - ${CONFIG_SOURCES} - ${SHLIB_LOADER_SOURCES} - ) - -target_link_libraries (nr-uesoftmodem-nos1 - -Wl,--start-group - RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_COMMON PHY_NR_UE PHY_UE PHY_RU LFDS NR_L2_UE MAC_NR_COMMON - ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} - -Wl,--end-group z dl) - -target_link_libraries (nr-uesoftmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-uesoftmodem-nos1 ${T_LIB}) - # USIM process ################# @@ -2586,37 +2541,64 @@ target_link_libraries (dlsim_tm4 add_executable(polartest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c) -target_link_libraries(polartest SIMU PHY PHY_NR PHY_COMMON PHY_NR_COMMON m ${ATLAS_LIBRARIES}) + ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/common/utils/system.c + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(polartest + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} dl + ) - -add_executable(smallblocktest +add_executable(smallblocktest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c) -target_link_libraries(smallblocktest SIMU PHY PHY_NR PHY_COMMON PHY_NR_COMMON m ${ATLAS_LIBRARIES}) + ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/common/utils/system.c + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} +) + + +target_link_libraries(smallblocktest + -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} dl + ) add_executable(ldpctest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c - ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c) -target_link_libraries(ldpctest SIMU PHY PHY_NR m ${ATLAS_LIBRARIES}) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(ldpctest + -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} dl + ) add_executable(nr_dlschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${T_SOURCE}) - target_link_libraries(nr_dlschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) + ${UTIL_SRC} + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_dlschsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${T_SOURCE}) -target_link_libraries(nr_pbchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} $(ITTI_LIB) dl) + ${UTIL_SRC} + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_pbchsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) #PUCCH ---> Prashanth add_executable(nr_pucchsim @@ -2625,45 +2607,63 @@ add_executable(nr_pucchsim ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/system.c ${UTIL_SRC} - ${T_SOURCE}) -target_link_libraries(nr_pucchsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_pucchsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) #PUCCH ---> Prashanth add_executable(nr_dlsim - ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${UTIL_SRC} - ${T_SOURCE}) -target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_dlsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) add_executable(nr_prachsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c - ${T_SOURCE}) -target_link_libraries(nr_prachsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) + ${UTIL_SRC} + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES}) +target_link_libraries(nr_prachsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/system.c ${UTIL_SRC} - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${T_SOURCE}) -target_link_libraries(nr_ulschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_ulschsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) add_executable(nr_ulsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c - ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/system.c + ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${UTIL_SRC} - ${T_SOURCE}) -target_link_libraries(nr_ulsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + ${T_SOURCE} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries(nr_ulsim + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl + ) foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) @@ -2744,10 +2744,10 @@ endforeach(myExe) if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) - lte-softmodem lte-uesoftmodem nr-softmodem nr-softmodem-nos1 - nr-uesoftmodem nr-uesoftmodem-nos1 dlsim dlsim_tm4 dlsim_tm7 + lte-softmodem lte-uesoftmodem nr-softmodem + nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim - syncsim ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim + syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim nr_ulschsim ldpctest polartest smallblocktest cu_test du_test #all "add_library" definitions @@ -2758,7 +2758,7 @@ if (${T_TRACER}) SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX - L2 L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U + L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB) if (TARGET ${i}) add_dependencies(${i} generate_T) diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index b94d99bff7..10c14fd59a 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -96,11 +96,41 @@ Obj.# Case# Test# Description (Test 4, 10 MHz, R3-1.FDD (MCS 16), AWGN, 12dB (70%)), (Test 5, 20 MHz, FDD (MCS 5), AWGN, 6dB (70%)), (Test 6, 20 MHz, FDD (MCS 16), AWGN, 12 dB (70%)) -01 51 02 pucchsim (TBD) -01 51 03 prachsim (TBD) -01 51 04 pdcchsim (TBD) -01 51 05 pbchsim (TBD) -01 51 06 mbmssim (TBD) +01 51 02 ldpc Test cases. (Test1: block length = 3872), + (Test2: block length = 4224), + (Test3: block length = 4576), + (Test4: block length = 4928), + (Test5: block length = 5280), + (Test6: block length = 5632), + (Test7: block length = 6336), + (Test8: block length = 7040), + (Test9: block length = 7744), + (Test10: block length = 8448) +01 51 03 polartest Test cases. (Test1: PBCH polar test), + (Test2: DCI polar test) +01 51 04 nr_pbchsim Test cases. (Test1: PBCH-only, 106 PRB), + (Test2: PBCH and synchronization, 106PBR), + (Test3: PBCH-only, 217 PRB), + (Test4: PBCH and synchronization, 217 RPB), + (Test5: PBCH-only, 273 PRB), + (Test6: PBCH and synchronization, 273 PRB) +01 51 05 nr_dlsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 06 nr_dlschsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 07 shortblocktest Test cases. (Test1: 3 bits), + (Test2: 6 bits), + (Test3: 7 bits), + (Test4: 11 bits) +01 51 08 nr_ulschsim Test cases. (Test1: 106 PRB), + (Test2: 217 PRB), + (Test3: 273 PRB) +01 51 09 nr_pucchsim Test cases. (Test1: Format 0 ACK miss 106 PRB), + (Test2: Format 1 ACK miss 106 PRB), + (Test3: Format 1 ACK miss 273 PRB), + (Test4: Format 1 NACKtoACK 106 PRB) 01 51 10 dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB), (Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)), (Test 6: 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)), @@ -110,8 +140,11 @@ Obj.# Case# Test# Description (Test 10: 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)), (Test 10b: 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)), (Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)) - (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), - (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), + (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), + (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), +01 51 11 nr_ulsim Test cases. (Test1: MCS 9), + (Test2: MCS 16), + (Test3: MCS 28) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index d30537424b..6795f2d1fa 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1081,18 +1081,35 @@ execution nr_dlsim Test cases. (Test1: 106 PRB), (Test2: 217 PRB), - (Test3: 273 PRB) + (Test3: 273 PRB), + (Test4: 106 PRB 12 CSET-Offset), + (Test5: 217 PRB 48 CSET-Offset), + (Test6: 106 PRB 25 PDSCH-Offset), + (Test7: 106 PRB 51 PDSCH-Offset), + (Test8: 217 PRB 100 PDSCH-PRBs), + (Test9: 217 PRB 80 PDSCH-Offset), + (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset), + (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28 $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15 - -n100 -R106 - -n100 -R217 - -n100 -R273 - nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 - PDCCH test OK + -n100 -R106 -b106 + -n100 -R217 -b217 + -n100 -R273 -b273 + -n100 -R106 -o12 + -n100 -R217 -o48 + -n100 -R106 -a25 + -n100 -R106 -a51 + -n100 -R217 -b100 + -n100 -R217 -a80 + -n100 -R217 -a110 -b100 + -n100 -e28 + nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 + nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 + PDSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1220,6 +1237,30 @@ 3 + + execution + nr_ulsim Test cases. (Test1: MCS 9 106 PRBs), + (Test2: MCS 16 50 PRBs), + (Test3: MCS 28 50 PRBs), + (Test4: MCS 9 217 PRBs), + (Test5: MCS 9 273 PRBs) + + $OPENAIR_DIR/cmake_targets/build_oai + --phy_simulators -c + $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash + + $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15 + -f100 -m9 -r106 -s10 + -f100 -m16 -s20 + -f100 -m28 -s30 + -f100 -m9 -R217 -r217 -s10 + -f100 -m9 -R273 -r273 -s10 + nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 + PUSCH test OK + segmentation fault|assertion|exiting|fatal + 3 + + lte-softmodem diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 220cd40c93..677095d43a 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -149,7 +149,7 @@ Options --build-eclipse Build eclipse project files. Paths are auto corrected by fixprj.sh --build-lib - Build optional shared library, can be one or several of $OPTIONAL_LIBRARIES + Build optional shared library, can be one or several of $OPTIONAL_LIBRARIES or \"all\" --usrp-recplay Build for I/Q record-playback modes -h | --help @@ -346,16 +346,21 @@ function main() { shift 1;; --build-lib) BUILD_OPTLIB="" - for alib in $2 ; do + if [ "$2" == "all" ] ; then + BUILD_OPTLIB="$OPTIONAL_LIBRARIES" + echo_info "Enabling build of all optional shared libraries ($OPTIONAL_LIBRARIES)" + else + for alib in $2 ; do for oklib in $OPTIONAL_LIBRARIES ; do - if [ "$alib" = "$oklib" ] ; then - BUILD_OPTLIB="$BUILD_OPTLIB $alib" - echo_info "Enabling build of lib${alib}.so" - fi + if [ "$alib" = "$oklib" ] ; then + BUILD_OPTLIB="$BUILD_OPTLIB $alib" + echo_info "Enabling build of lib${alib}.so" + fi + done done - done - if [ "${BUILD_OPTLIB## }" != "$2" ] ; then - echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES" + if [ "${BUILD_OPTLIB## }" != "$2" ] ; then + echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES" + fi fi shift 2;; --usrp-recplay) @@ -580,7 +585,8 @@ function main() { nr-uesoftmodem $dbin/nr-uesoftmodem.$REL fi -# mandatory shared lib +# mandatory shared libraries common to UE and (e/g)NB + compilations \ $build_dir $config_libconfig_shlib \ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so @@ -864,7 +870,6 @@ function main() { ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so echo_info "liboai_transpro.so is linked to ETHERNET transport" fi - ################### # Doxygen Support # diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 4af81a1a22..99a2e3f589 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -103,6 +103,7 @@ check_supported_distribution() { "fedora24") return 0 ;; "rhel7") return 0 ;; "rhel7.6") return 0 ;; + "rhel7.7") return 0 ;; "centos7") return 0 ;; esac return 1 diff --git a/common/config/DOC/config/devusage/api.md b/common/config/DOC/config/devusage/api.md index 06c22dba6f..376e59abaf 100644 --- a/common/config/DOC/config/devusage/api.md +++ b/common/config/DOC/config/devusage/api.md @@ -1,3 +1,5 @@ +## config module management + ```c configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags) ``` @@ -14,23 +16,17 @@ void End_configmodule(void) * Free memory which has been allocated by the configuration module since its initialization. * Possibly calls the `config__end` function +## Retrieving parameter's values + ```c int config_get(paramdef_t *params,int numparams, char *prefix) ``` * Reads as many parameters as described in params, they must all be in the same configuration file section * Calls the `config__get` function * Calls the `config_process_cmdline` function -* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function. The following bits can possibly be set in the `paramflags` mask before calling - - `PARAMFLAG_MANDATORY`: -1 is returned if the parameter is not explicitly defined in the config source. - - `PARAMFLAG_DISABLECMDLINE`: parameter cannot be modified via the command line - - `PARAMFLAG_DONOTREAD`: ignore the parameter, can be used at run-time, to alter a pre-defined `paramdef_t` array which is used in several `config_get` or/and `config_getlist` calls. - - `PARAMFLAG_NOFREE`: do not free the memory possibly allocated by the config module to store the value of the parameter. Default behavior is for the config module to free the memory it has allocated when the `config_end` function is called. - - `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1. +* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function.The `paramflags` bit mask can be used to modify how a specific parameter is processed and the same mask is also used by the configuration module to return information about how the parameter has been processed. Bits definitions are described in the [`paramdef_t` structure description](./struct.md) + -* `params` is also used as an output parameter, `< XXX >ptr >` field is used by the config module to store the value it has read. The following bits can possibly be set in the `paramflags` mask after the call: - - `PARAMFLAG_MALLOCINCONFIG`: memory has been allocated for the ` < XXX >ptr > ` field - - `PARAMFLAG_PARAMSET`: parameter has been found in the config source, it is not set to default value. - - `PARAMFLAG_PARAMSET`: parameter has been set to its default value * `numparams` is the number of entries in the params array * `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology). * The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured @@ -44,6 +40,9 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int * `ParamList` points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters. * The returned value is the number of occurrences in the list or -1 in case of severe error +## utility functions and macros + +The configuration module also defines APIs to access the `paramdef_t` and `configmodule_interface_t` fields. They are listed in the configuration module [include file `common/config/config_userapi.h`](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.h) [Configuration module developer main page](../../config/devusage.md) [Configuration module home](../../config.md) diff --git a/common/config/DOC/config/devusage/struct.md b/common/config/DOC/config/devusage/struct.md index e8b15fc0f1..4c9cd15785 100644 --- a/common/config/DOC/config/devusage/struct.md +++ b/common/config/DOC/config/devusage/struct.md @@ -5,6 +5,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla |:-----------|:------------------------------------------------------------------|----:| | `optname` | parameter name, as used when looking for it in the config source, 63 bytes max (64 with trailing \0) | I | | `helstr` | pointer to a C string printed when using --help on the command line | I | +| `paramflags` | bit mask, used to modify how the parameter is processed, or to return to the API caller how the parameter has been set, see list in the next table | IO | | `strptr` `strlistptr` `u8ptr` `i8ptr` `u16ptr` `i16ptr` `uptr` `iptr` `u64ptr` `i64ptr` `dblptr` `voidptr` | a pointer to a variable where the parameter value(s) will be returned. This field is an anonymous union, the supported pointer types have been built to avoid type mismatch warnings at compile time. | O | | `defstrval` `defstrlistval` `defuintval` `defintval` `defint64val` `defintarrayval` `defdblval` | this field is an anonymous union, it can be used to define the default value for the parameter. It is ignored if `PARAMFLAG_MANDATORY` is set in the `paramflags` field.| I | | `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field, `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The `numelt` field gives the number of item in the array. | I | @@ -12,6 +13,22 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla | `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I | | `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O | +## `paramflags` bits definition + + +| C macro bit definition | usage | I/O | +|:-------------------------------------|:---------------------------------------------------------------------------------------------------------------------|----:| +| `PARAMFLAG_MANDATORY` | parameter is mandatory, comfiguration module will stop the process if it is not specified. Default value is ignored | I | +| `PARAMFLAG_DISABLECMDLINE` | parameter cannot be specified on the command line | I | +| `PARAMFLAG_DONOTREAD` | ignore the parameter, usefull when a parameter group is used in different context | I | +| `PARAMFLAG_NOFREE` | The end_configmodule API won't free the memory which has been possibly allocated to store the value of the parameter.| I | +| `PARAMFLAG_BOOL` | Parameter is a boolean, it can be specified without a value to set it to true | I | +| `PARAMFLAG_CMDLINE_NOPREFIXENABLED` | parameter can be specified without the prefix on the command line. Must be used with care, carefuly checking unicity, especially for short parameter names | I | +| `PARAMFLAG_MALLOCINCONFIG` | Memory for the parameter value has been allocated by the configuration module |O | +| `PARAMFLAG_PARAMSET` | Parameter value has been explicitely set, as the parameter was specified either on the command line or the config source | O | +| `PARAMFLAG_PARAMSETDEF` | Parameter value has been set to it's default | O | + + # `paramlist_def_t`structure It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160). It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters. diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index 249765a46e..6d01d98c65 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -167,8 +167,8 @@ int config_check_unknown_cmdlineopt(char *prefix) { char testprefix[CONFIG_MAXOPTLENGTH]; int finalcheck = 0; memset(testprefix,0,sizeof(testprefix)); - memset(testprefix,0,sizeof(testprefix)); + if (prefix != NULL) { if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0) finalcheck = 1; @@ -253,7 +253,9 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) } if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */ - ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) ) { + ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */ + ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) || + ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) { char *valptr=NULL; int ret; config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index 9aad79960d..86fc993a08 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -45,7 +45,7 @@ #define PARAMFLAG_DONOTREAD (1 << 2) // parameter must be ignored in get function #define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function #define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1 - +#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix /* Flags used by config modules to return info to calling modules and/or to for internal usage*/ #define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index bf0ae01cf7..cbb0d4c0a7 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -81,7 +81,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { } if (*ptr == NULL) { - *ptr = malloc(length); + *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch if ( *ptr != NULL) { memset(*ptr,0,length); @@ -172,7 +172,7 @@ int config_get_processedint(paramdef_t *cfgoption) { return ret; } void config_printhelp(paramdef_t *params,int numparams, char *prefix) { - printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix ,numparams); + printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix,numparams); for (int i=0 ; inumelt == 0 ) { - config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *)); config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1); sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval); printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr)); } else { - sprintf((char *)*(cfgoptions->strptr), "%s",cfgoptions->defstrval); - printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)*(cfgoptions->strptr)); + sprintf((char *)(cfgoptions->strptr), "%s",cfgoptions->defstrval); + printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)(cfgoptions->strptr)); } } @@ -437,7 +446,7 @@ int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) { status=1; for (int j=0; jnumelt ; j++) { - printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname ,j,(int)cfgoptions->iptr[j]); + printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname,j,(int)cfgoptions->iptr[j]); } } @@ -451,7 +460,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { *(cfgoptions->dblptr)=cfgoptions->defdblval; status=1; - printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr)); + printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname, *(cfgoptions->dblptr)); } return status; @@ -459,7 +468,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) { config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int)); - int rst=inet_pton(AF_INET, ipv4addr ,cfgoptions->uptr ); + int rst=inet_pton(AF_INET, ipv4addr,cfgoptions->uptr ); if (rst == 1 && *(cfgoptions->uptr) > 0) { printf_params("[CONFIG] %s: %s\n",cfgoptions->optname, ipv4addr); diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index cc07b1af5f..c00526aa4c 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -39,6 +39,7 @@ extern "C" { #endif +/* utility functions to ease usage of config module structures */ #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) #define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] ) @@ -46,6 +47,8 @@ extern "C" #define CONFIG_SETRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags |= P; } #define CONFIG_CLEARRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags &= (~P); } #define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) +extern int config_paramidx_fromname(paramdef_t *params,int numparams, char *name); + /* utility functions, to be used by configuration module and/or configuration libraries */ extern configmodule_interface_t *config_get_if(void); extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 1108eb46da..7f177b90ce 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -232,7 +232,7 @@ int write_file_matlab(const char *fname, void log_getconfig(log_t *g_log) { char *gloglevel = NULL; - int consolelog ; + int consolelog = 0; paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC; paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS]; paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS]; @@ -324,7 +324,9 @@ void log_getconfig(log_t *g_log) config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); - config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX); + + if (config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX) > 0) + exit(1); /* set the debug mask according to the debug parameters values */ for (int i=0; log_maskmap[i].name != NULL ; i++) { @@ -434,6 +436,10 @@ int logInit (void) register_log_component("ASN","log",ASN); register_log_component("NFAPI_VNF","log",NFAPI_VNF); register_log_component("NFAPI_PNF","log",NFAPI_PNF); + register_log_component("GNB_APP","log",GNB_APP); + register_log_component("NR_RRC","log",NR_RRC); + register_log_component("NR_MAC","log",NR_MAC); + register_log_component("NR_PHY","log",NR_PHY); for (int i=0 ; log_level_names[i].name != NULL ; i++) g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index cee14a27af..111f2c58ce 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -25,7 +25,6 @@ * \date 2009 - 2014 * \version 0.5 * @ingroup util - */ #ifndef __LOG_H__ @@ -297,7 +296,7 @@ extern "C" { # include "log_if.h" /*----------------------------------------------------------------------------*/ int logInit (void); -int isLogInitDone (void); +int isLogInitDone (void); void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args ); void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ); @@ -363,14 +362,14 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int -/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* LOG globalconfiguration parameters */ -/* optname help paramflags XXXptr defXXXval type numelt */ -/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* LOG globalconfiguration parameters */ +/* optname help paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOG_GLOBALPARAMS_DESC { \ - {LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \ - {LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \ - {LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \ + {LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \ + {LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \ + {LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0} \ } #define LOG_OPTIONS_IDX 2 diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index b3a1aaad07..63c5336bd8 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -247,7 +247,8 @@ const char* eurecomVariablesNames[] = { "slot_number_TX0_gNB", "slot_number_TX1_gNB", "slot_number_RX0_gNB", - "slot_number_RX1_gNB" + "slot_number_RX1_gNB", + "ru_tx_ofdm_mask" }; const char* eurecomFunctionsNames[] = { @@ -328,6 +329,13 @@ const char* eurecomFunctionsNames[] = { "phy_procedures_ru_feptx_ofdm7", "phy_procedures_ru_feptx_ofdm8", "phy_procedures_ru_feptx_ofdm9", + "phy_procedures_ru_feptx_ofdm10", + "phy_procedures_ru_feptx_ofdm11", + "phy_procedures_ru_feptx_ofdm12", + "phy_procedures_ru_feptx_ofdm13", + "phy_procedures_ru_feptx_ofdm14", + "phy_procedures_ru_feptx_ofdm15", + "phy_procedures_ru_feptx_ofdm16", "phy_procedures_ru_feptx_prec0", "phy_procedures_ru_feptx_prec1", "phy_procedures_ru_feptx_prec2", @@ -502,6 +510,7 @@ const char* eurecomFunctionsNames[] = { "pdcch_interleaving", "pdcch_tx", /*NR softmodem signal*/ + "wakeup_txfh", "gNB_thread_rxtx0", "gNB_thread_rxtx1" }; @@ -634,7 +643,7 @@ void *vcd_dumper_thread_rt(void *args) uint32_t data_ready_wait; # if defined(ENABLE_ITTI) - signal_mask(); + return 0; //signal_mask(); //function defined at common/utils/ocp_itti/intertask_interface.cpp # endif sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1; diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index a7c4c10fe3..3a6fb6d6ab 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -225,6 +225,7 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, VCD_SIGNAL_DUMPER_VARIABLES_END @@ -309,6 +310,13 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM7, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM8, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM9, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM10, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM11, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM12, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM13, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM14, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM15, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM16, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC1, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC2, @@ -494,6 +502,7 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX, /*NR softmodem signal*/ + VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 4f2b10c3ae..ab275d4d62 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -73,10 +73,10 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (237)//(232) +#define VCD_NUM_FUNCTIONS (245) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES (185) +#define VCD_NUM_VARIABLES (186) /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 0b10b6e25e..407bb66be1 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -2050,6 +2050,11 @@ ID = VCD_VARIABLE_SLOT_NUMBER_RX1_GNB GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value VCD_NAME = slot_number_RX1_gNB +ID = VCD_VARIABLE_RU_TX_OFDM_MASK + DESC = VCD variable RU_TX_OFDM_MASK + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ru_tx_ofdm_mask #functions @@ -2418,6 +2423,41 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM9 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = phy_procedures_ru_feptx_ofdm9 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM10 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM10 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm10 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM11 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM11 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm11 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM12 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM12 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm12 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM13 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM13 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm13 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM14 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM14 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm14 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM15 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM15 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm15 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM16 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM16 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm16 ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC GROUP = ALL:VCD:ENB:VCD_FUNCTION @@ -3230,6 +3270,11 @@ ID = VCD_FUNCTION_PDCCH_TX VCD_NAME = pdcch_tx #function for gNB +ID = VCD_FUNCTION_WAKEUP_TXFH + DESC = VCD function WAKEUP_TXFH + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = wakeup_txfh ID = VCD_FUNCTION_gNB_PROC_RXTX0 DESC = VCD function gNB_PROC_RXTX0 GROUP = ALL:VCD:ENB:VCD_FUNCTION diff --git a/common/utils/hashtable/hashtable.c b/common/utils/hashtable/hashtable.c index 50c2ec8324..e9641f8e0c 100644 --- a/common/utils/hashtable/hashtable.c +++ b/common/utils/hashtable/hashtable.c @@ -162,34 +162,6 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtblP, cons return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void functP(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP) -//------------------------------------------------------------------------------------------------------------------------------- -{ - hash_node_t *node = NULL; - unsigned int i = 0; - unsigned int num_elements = 0; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - - while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) { - if (hashtblP->nodes[i] != NULL) { - node=hashtblP->nodes[i]; - - while(node) { - num_elements += 1; - functP(node->key, node->data, parameterP); - node=node->next; - } - } - - i += 1; - } - - return HASH_TABLE_OK; -} -//------------------------------------------------------------------------------------------------------------------------------- hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ) //------------------------------------------------------------------------------------------------------------------------------- { @@ -266,7 +238,6 @@ hashtable_rc_t hashtable_insert(hash_table_t *const hashtblP, const hash_key_t k } hashtblP->nodes[hash]=node; - hashtblP->num_elements += 1; return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- @@ -295,7 +266,6 @@ hashtable_rc_t hashtable_remove(hash_table_t *const hashtblP, const hash_key_t k } free(node); - hashtblP->num_elements -= 1; return HASH_TABLE_OK; } @@ -335,47 +305,3 @@ hashtable_rc_t hashtable_get(const hash_table_t *const hashtblP, const hash_key_ *dataP = NULL; return HASH_TABLE_KEY_NOT_EXISTS; } -//------------------------------------------------------------------------------------------------------------------------------- -/* - * Resizing - * The number of elements in a hash table is not always known when creating the table. - * If the number of elements grows too large, it will seriously reduce the performance of most hash table operations. - * If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table. - * Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position. - * We create a temporary hash_table_t object (newtbl) to be used while building the new hashes. - * This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table. - * After that, we can just free the old table and copy the elements from newtbl to hashtbl. - */ - -hashtable_rc_t hashtable_resize(hash_table_t *const hashtblP, const hash_size_t sizeP) { - hash_table_t newtbl; - hash_size_t n; - hash_node_t *node,*next; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - - newtbl.size = sizeP; - newtbl.hashfunc = hashtblP->hashfunc; - newtbl.num_elements = 0; - - if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t *)))) return -1; - - for(n=0; nsize; ++n) { - for(node=hashtblP->nodes[n]; node; node=next) { - next = node->next; - hashtable_insert(&newtbl, node->key, node->data); - // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN - hashtable_remove(hashtblP, node->key); - } - } - - free(hashtblP->nodes); - hashtblP->size=newtbl.size; - hashtblP->nodes=newtbl.nodes; - return HASH_TABLE_OK; -} - - - diff --git a/common/utils/hashtable/hashtable.h b/common/utils/hashtable/hashtable.h index 3f770684fa..09f8623ce2 100644 --- a/common/utils/hashtable/hashtable.h +++ b/common/utils/hashtable/hashtable.h @@ -49,7 +49,6 @@ typedef struct hash_node_s { typedef struct hash_table_s { hash_size_t size; - hash_size_t num_elements; struct hash_node_s **nodes; hash_size_t (*hashfunc)(const hash_key_t); void (*freefunc)(void *); @@ -60,12 +59,10 @@ void hash_free_int_func(void *memoryP); hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void *)); hashtable_rc_t hashtable_destroy(hash_table_t **hashtbl); hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtbl, const uint64_t key); -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void funct(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP); hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ); hashtable_rc_t hashtable_insert (hash_table_t *const hashtbl, const hash_key_t key, void *data); hashtable_rc_t hashtable_remove (hash_table_t *const hashtbl, const hash_key_t key); hashtable_rc_t hashtable_get (const hash_table_t *const hashtbl, const hash_key_t key, void **dataP); -hashtable_rc_t hashtable_resize (hash_table_t *const hashtbl, const hash_size_t size); diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 484cd8aa26..cdbf59cd76 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -37,8 +37,8 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; int tmp2 = locationAndBandwidth%N_RB; - if (tmp <= (N_RB-tmp2+1)) return(tmp); - else return(N_RB-tmp); + if (tmp <= ((N_RB>>1)-tmp2+1)) return(tmp+1); + else return(N_RB+1-tmp); } @@ -46,17 +46,19 @@ int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; int tmp2 = locationAndBandwidth%N_RB; - if (tmp <= (N_RB-tmp2+1)) return(tmp2); - else return(N_RB-tmp2); + if (tmp <= ((N_RB>>1)-tmp2+1)) return(tmp2); + else return(N_RB-1-tmp2); +} + +int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) { + AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d)\n",NPRB,RBstart); + if (NPRB <= 1+(BWPsize>>1)) return(BWPsize*(NPRB-1)+RBstart); + else return(BWPsize*(BWPsize+1-NPRB) + (BWPsize-1-RBstart)); } int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) { - if (NPRB < 138) - return(275*(NPRB-1)+RBstart); - else - return(275*(276-NPRB) + (274-RBstart)); + return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275)); } - /// Target code rate tables indexed by Imcs uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \ 616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948}; @@ -128,3 +130,18 @@ int get_subband_size(int NPRB,int size) { AssertFatal(1==0,"Shouldn't get here, NPRB %d\n",NPRB); } + +void SLIV2SL(int SLIV,int *S,int *L) { + + int SLIVdiv14 = SLIV/14; + int SLIVmod14 = SLIV%14; + // Either SLIV = 14*(L-1) + S, or SLIV = 14*(14-L+1) + (14-1-S). Condition is 0 <= L <= 14-S + if ((SLIVdiv14 + 1) >= 0 && (SLIVdiv14 <= 13-SLIVmod14)) { + *L=SLIVdiv14+1; + *S=SLIVmod14; + } else { + *L=15-SLIVdiv14; + *S=13-SLIVmod14; + } + +} diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index c4ac58413e..979cf86343 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -35,6 +35,7 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); +int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize); int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart); extern uint16_t nr_target_code_rate_table1[29]; extern uint16_t nr_target_code_rate_table2[28]; @@ -43,3 +44,22 @@ extern uint16_t nr_tbs_table[93]; uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); int get_subband_size(int NPRB,int size); +void SLIV2SL(int SLIV,int *S,int *L); + + +#define CEILIDIV(a,b) ((a+b-1)/b) +#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) + +#define cmax(a,b) ((a>b) ? (a) : (b)) +#define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) +#define cmin(a,b) ((a typedef struct timer_elm_s { - timer_type_t type; ///< Timer type - long instance; + timer_type_t type; ///< Timer type + long instance; long duration; uint64_t timeout; - void *timer_arg; ///< Optional argument that will be passed when timer expires + void *timer_arg; ///< Optional argument that will be passed when timer expires } timer_elm_t ; typedef struct task_list_s { diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 868a9ba245..80493dc816 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -25,7 +25,7 @@ typedef struct { typedef struct { uint32_t interval_sec; uint32_t interval_us; - long task_id; + long task_id; int32_t instance; timer_type_t type; void *timer_arg; @@ -33,7 +33,7 @@ typedef struct { } timer_create_t; typedef struct { - long task_id; + long task_id; long timer_id; } timer_delete_t; @@ -536,6 +536,7 @@ int timer_setup( int timer_remove(long timer_id); #define timer_stop timer_remove int signal_handle(int *end); +int signal_mask(void); #ifdef __cplusplus } diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 7f8645be02..44ab07a49b 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -123,7 +123,7 @@ void client_printf(const char *message, ...) { if (telnetparams.new_socket > 0) { vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args); - send(telnetparams.new_socket,telnetparams.msgbuff , strlen(telnetparams.msgbuff), MSG_NOSIGNAL); + send(telnetparams.new_socket,telnetparams.msgbuff, strlen(telnetparams.msgbuff), MSG_NOSIGNAL); } else { vprintf(message, va_args); } @@ -475,7 +475,7 @@ int process_command(char *buf) { memset(cmdb,0,sizeof(cmdb)); bufbck=strdup(buf); rt=CMDSTATUS_NOTFOUND; - j = sscanf(buf,"%9s %9s %9[^\t\n]",modulename,cmd,cmdb); + j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb); if (telnetparams.telnetdbg > 0) printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); @@ -543,7 +543,7 @@ void run_telnetsrv(void) { char buf[TELNET_MAX_MSGLENGTH]; struct sockaddr cli_addr; unsigned int cli_len = sizeof(cli_addr); - int readc , filled; + int readc, filled; int status; int optval = 1; pthread_setname_np(pthread_self(), "telnet"); @@ -604,7 +604,7 @@ void run_telnetsrv(void) { } if (telnetparams.telnetdbg > 0) - printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf); + printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf); if (buf[0] == '!') { if (buf[1] == '!') { diff --git a/common/utils/threadPool/Makefile b/common/utils/threadPool/Makefile index af0b44996c..6b28eb2ba8 100644 --- a/common/utils/threadPool/Makefile +++ b/common/utils/threadPool/Makefile @@ -1,8 +1,13 @@ -all: measurement_display thread-pool-test +all: +measurement_display thread-pool-test -measurement_display: measurement_display.c thread-pool.h - gcc measurement_display.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display +measurement_display: +measurement_display.c thread-pool.h +gcc measurement_display.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o +measurement_display -thread-pool-test: thread-pool.c thread-pool.h - gcc -g thread-pool.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -I ${OPENAIR_DIR}/openair2/COMMON ${OPENAIR_DIR}/common/utils/LOG/log.c ${OPENAIR_DIR}/common/config/config_userapi.c ${OPENAIR_DIR}/common/config/config_load_configmodule.c ${OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test +thread-pool-test: +thread-pool.c thread-pool.h +gcc -g thread-pool.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -I $ {OPENAIR_DIR}/openair2/COMMON $ {OPENAIR_DIR}/common/utils/LOG/log.c $ {OPENAIR_DIR}/common/config/config_userapi.c +$ {OPENAIR_DIR}/common/config/config_load_configmodule.c $ {OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index b45a8fa722..dd3d16d717 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -67,7 +67,7 @@ void *one_thread(void *arg) { delNotifiedFIFO_elt(elt); else pushNotifiedFIFO(elt->reponseFifo, elt); - + myThread->runningOnKey=-1; mutexunlock(tp->incomingFifo.lockF); } } while (true); @@ -95,7 +95,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { pool->nbThreads=0; pool->restrictRNTI=false; curptr=strtok_r(params,",",&saveptr); - + struct one_thread * ptr; while ( curptr!=NULL ) { int c=toupper(curptr[0]); @@ -109,8 +109,9 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { break; default: + ptr=pool->allthreads; pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); - pool->allthreads->next=pool->allthreads; + pool->allthreads->next=ptr; printf("create a thread for core %d\n", atoi(curptr)); pool->allthreads->coreID=atoi(curptr); pool->allthreads->id=pool->nbThreads; diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index d6dc332c5a..9a2681a828 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -150,8 +150,9 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) { // This function aborts all messages matching the key // If the queue is used in thread pools, it doesn't cancels already running processing // because the message has already been picked -static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { +static inline int abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { mutexlock(nf->lockF); + int nbDeleted=0; notifiedFIFO_elt_t **start=&nf->outF; while(*start!=NULL) { @@ -159,13 +160,16 @@ static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbDeleted++; + } else start=&(*start)->next; } + if (nf->outF == NULL) + nf->inF=NULL; + mutexunlock(nf->lockF); + return nbDeleted; } struct one_thread { @@ -195,7 +199,20 @@ typedef struct thread_pool { static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { if (t->measurePerf) msg->creationTime=rdtsc(); - pushNotifiedFIFO(&t->incomingFifo, msg); + if ( t->activated) + pushNotifiedFIFO(&t->incomingFifo, msg); + else { + if (t->measurePerf) + msg->startProcessingTime=rdtsc(); + + msg->processingFunc(NotifiedFifoData(msg)); + + if (t->measurePerf) + msg->endProcessingTime=rdtsc(); + + if (msg->reponseFifo) + pushNotifiedFIFO(msg->reponseFifo, msg); + } } static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { @@ -225,7 +242,8 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo return msg; } -static inline void abortTpool(tpool_t *t, uint64_t key) { +static inline int abortTpool(tpool_t *t, uint64_t key) { + int nbRemoved=0; notifiedFIFO_t *nf=&t->incomingFifo; mutexlock(nf->lockF); notifiedFIFO_elt_t **start=&nf->outF; @@ -235,22 +253,27 @@ static inline void abortTpool(tpool_t *t, uint64_t key) { notifiedFIFO_elt_t *request=*start; *start=(*start)->next; delNotifiedFIFO_elt(request); - } - - if (*start != NULL) + nbRemoved++; + } else start=&(*start)->next; } + if (t->incomingFifo.outF==NULL) + t->incomingFifo.inF=NULL; + struct one_thread *ptr=t->allthreads; while(ptr!=NULL) { - if (ptr->runningOnKey==key) + if (ptr->runningOnKey==key) { ptr->abortFlag=true; + nbRemoved++; + } ptr=ptr->next; } mutexunlock(nf->lockF); + return nbRemoved; } void initTpool(char *params,tpool_t *pool, bool performanceMeas); diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index 2b6336fb60..bc1b1db54a 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -3,69 +3,90 @@ The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores. Each worker loop on pick from the same input queue jobs to do. + When a job is done, the worker sends a return if a return is defined. -A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). + A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). -All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. + All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, + so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. ## license -Author: Laurent Thomas, Open cells project -The owner share this piece code to Openairsoftware alliance as per OSA license terms + Author: + Laurent Thomas, Open cells project + The owner share this piece code to Openairsoftware alliance as per OSA license terms # jobs -A job is a message (notifiedFIFO_elt_t): -next: internal FIFO chain, do not set it -key: a long int that the client can use to identify a message or a group of messages -responseFifo: if the client defines a response FIFO, the message will be posted back after processing -processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch -msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing -malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature + A job is a message (notifiedFIFO_elt_t): + next: + internal FIFO chain, do not set it + key: + a long int that the client can use to identify a message or a group of messages + responseFifo: + if the client defines a response FIFO, the message will be posted back after processing + processingFunc: + any funtion (type void processingFunc(void *)) that the worker will launch + msgData: + the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing + malloced: + a boolean that enable internal free in these cases: + no return Fifo or Abort feature -The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. + The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. # Queues of jobs -Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO() -No delete function is required, the creator has only to free the data of type notifiedFIFO_t + Queues are type of: + notifiedFIFO_t that must be initialized by init_notifiedFIFO() + No delete function is required, the creator has only to free the data of type notifiedFIFO_t -push_notifiedFIFO() add a job in the queue -pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking + push_notifiedFIFO() add a job in the queue + pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking -abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) + abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) # Thread pools ## initialization -The clients can create one or more thread pools with init_tpool() -the params string structure: describes a list of cores, separated by "," that run a worker thread + The clients can create one or more thread pools with init_tpool() + the params string structure: + describes a list of cores, separated by "," that run a worker thread -If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core). + If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and + the related code (use negative values is allowed, so the thread will never be mapped on a specific core). -The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" + The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" ## adding jobs -The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) + The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) -If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. + If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. ## abort -A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. + A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. -Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. + Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. ## Performance measurements -A performance measurement is integrated: the pool will automacillay fill timestamps: + A performance measurement is integrated: + the pool will automacillay fill timestamps: -* creationTime: time the request is push to the pool; -* startProcessingTime: time a worker start to run on the job -* endProcessingTime: time the worker finished the job -* returnTime: time the client reads the result + * creationTime: + time the request is push to the pool; -if you set the environement variable: thread-pool-measurements to a valid file name +* startProcessingTime: +time a worker start to run on the job +* endProcessingTime: +time the worker finished the job +* returnTime: +time the client reads the result + +if you set the environement variable: +thread-pool-measurements to a valid file name These measurements will be wrote to this Linux pipe. -A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests. +A tool to read the linux fifo and display it in ascii is provided: +see the local directory Makefile for this tool and to compile the thread pool unitary tests. diff --git a/doc/BUILD.md b/doc/BUILD.md index 65567cefa4..388f9f2658 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -54,7 +54,7 @@ cd cmake_targets/ ``` - The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. -- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. +- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be build using `-w SIMU` option. - `--eNB` is to build the `lte-softmodem` executable and all required shared libraries - `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 6ece377293..732534ad68 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -99,17 +99,17 @@ #if defined(ENABLE_ITTI) - extern volatile int start_gNB; - extern volatile int start_UE; + extern volatile int start_gNB; + extern volatile int start_UE; #endif -extern volatile int oai_exit; +extern volatile int oai_exit; extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int transmission_mode; -uint16_t sl_ahead=4; -uint16_t sf_ahead=4; +uint16_t sl_ahead=6; +uint16_t sf_ahead=6; //pthread_t main_gNB_thread; time_stats_t softmodem_stats_mt; // main thread @@ -133,13 +133,14 @@ extern double cpuf; void init_gNB(int,int); void stop_gNB(int nb_inst); -int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx); -int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx); -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); +int wakeup_txfh(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int frame_tx, int slot_tx, uint64_t timestamp_tx); +int wakeup_tx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, uint64_t timestamp_tx); +#include "executables/thread-common.h" +//extern PARALLEL_CONF_t get_thread_parallel_conf(void); +//extern WORKER_CONF_t get_thread_worker_conf(void); -void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe); +void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe); extern uint8_t nfapi_mode; extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); @@ -149,7 +150,7 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) -static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { +static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* @@ -184,17 +185,15 @@ static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx // **************************************** // Common RX procedures subframe n T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); - /* - // if this is IF5 or 3GPP_gNB - if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { - wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx); - } +/* + // if this is IF5 or 3GPP_gNB + if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) { + wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx); + } + + // UE-specific RX processing for subframe n + if (nfapi_mode == 0 || nfapi_mode == 1) */ - // UE-specific RX processing for subframe n - if (nfapi_mode == 0 || nfapi_mode == 1) { - phy_procedures_gNB_uespec_RX(gNB, proc, no_relay ); - } - */ pthread_mutex_lock(&gNB->UL_INFO_mutex); gNB->UL_INFO.frame = frame_rx; gNB->UL_INFO.slot = slot_rx; @@ -213,6 +212,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB,int frame_rx, int slot_rx, int frame_tx if (oai_exit) return(-1); + //if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD) + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); + if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); } @@ -288,6 +290,8 @@ static void *gNB_L1_thread_tx(void *param) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 ); pthread_mutex_lock( &L1_proc_tx->mutex ); L1_proc_tx->instance_cnt = -1; @@ -299,6 +303,7 @@ static void *gNB_L1_thread_tx(void *param) { pthread_mutex_unlock(&L1_proc_tx->mutex); wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); } @@ -418,10 +423,10 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); - waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",1000000); + waitret=wait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh"); + AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); - AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); if (waitret == ETIMEDOUT) { @@ -446,7 +451,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ru = gNB->RU_list[i]; ru_proc = &ru->proc; - AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); + //AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); if (ru_proc->instance_cnt_gNBs == 0) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); @@ -454,7 +459,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); gNB->proc.RU_mask_tx = 0; AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); + //AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); return(-1); @@ -520,6 +525,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { RU_proc_t *ru_proc=&ru->proc; int ret; int i; + struct timespec abstime; + int time_ns = 50000; AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); for (i=0;inum_RU;i++) { @@ -540,14 +547,22 @@ 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+sl_ahead // lock the TX mutex and make sure the thread is ready - AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex)) == 0,"mutex_lock returns %d\n", ret); + 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; @@ -929,13 +944,13 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { #ifndef OCP_FRAMEWORK LOG_I(PHY,"Initializing gNB %d\n",inst); #endif + LOG_I(PHY,"Registering with MAC interface module (before %p)\n",gNB->if_inst); AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface"); LOG_I(PHY,"Registering with MAC interface module (after %p)\n",gNB->if_inst); gNB->if_inst->NR_Schedule_response = nr_schedule_response; gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); - memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); LOG_I(PHY,"Setting indication lists\n"); gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list; gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list; diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 5bf7ef24ce..44a740a0db 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -81,6 +81,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "enb_config.h" +#include #ifdef SMBV #include "PHY/TOOLS/smbv.h" @@ -90,7 +91,8 @@ unsigned short config_frames[4] = {2,9,11,13}; /* these variables have to be defined before including ENB_APP/enb_paramdef.h and GNB_APP/gnb_paramdef.h */ static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; - +static int DEFBFW[] = {0x00007fff}; + //static int DEFNRBANDS[] = {7}; //static int DEFGNBS[] = {0}; @@ -114,27 +116,22 @@ static int DEFENBS[] = {0}; #include "T.h" #include "nfapi_interface.h" -extern volatile int oai_exit; +extern volatile int oai_exit; extern void nr_phy_free_RU(RU_t *); extern void nr_phy_config_request(NR_PHY_Config_t *gNB); - -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); +#include "executables/thread-common.h" +//extern PARALLEL_CONF_t get_thread_parallel_conf(void); +//extern WORKER_CONF_t get_thread_worker_conf(void); void init_NR_RU(char *); void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); -void configure_ru(int idx, - void *arg); - -void configure_rru(int idx, - void *arg); - +void configure_ru(int idx, void *arg); +void configure_rru(int idx, void *arg); int attach_rru(RU_t *ru); - int connect_rau(RU_t *ru); extern uint16_t sl_ahead; @@ -303,7 +300,7 @@ int connect_rau(RU_t *ru) /* Southbound Fronthaul functions, RCC/RAU */ // southbound IF5 fronthaul for 16-bit OAI format -static inline void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) +void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); @@ -311,14 +308,15 @@ static inline void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t time } // southbound IF4p5 fronthaul -static inline void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) +void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); - if ((nr_slot_select(ru->nr_frame_parms,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0) + if ((nr_slot_select(cfg,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0) send_IF4p5(ru,frame, slot, IF4p5_PDLFFT); } @@ -521,7 +519,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) { void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; RU_proc_t *proc = &ru->proc; uint16_t packet_type; uint32_t symbol_number,symbol_mask,symbol_mask_full=0; @@ -534,10 +532,10 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { do { recv_IF4p5(ru, &frame_tx, &slot_tx, &packet_type, &symbol_number); - if (((nr_slot_select(ru->nr_frame_parms,frame_tx,slot_tx) & NR_DOWNLINK_SLOT) > 0) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); + if (((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT) > 0) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); - LOG_D(PHY,"subframe %d (%d): frame %d, subframe %d, symbol %d\n", - *slot,nr_slot_select(ru->nr_frame_parms,frame_tx,*slot),frame_tx,slot_tx,symbol_number); + LOG_D(PHY,"slot %d (%d): frame %d, slot %d, symbol %d\n", + *slot,nr_slot_select(cfg,frame_tx,*slot),frame_tx,slot_tx,symbol_number); if (proc->first_tx != 0) { *frame = frame_tx; @@ -556,7 +554,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { } else AssertFatal(1==0,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type); } while (symbol_mask != symbol_mask_full); - if ((nr_slot_select(ru->nr_frame_parms,frame_tx,slot_tx) & NR_DOWNLINK_SLOT)>0) stop_meas(&ru->rx_fhaul); + if ((nr_slot_select(cfg,frame_tx,slot_tx) & NR_DOWNLINK_SLOT)>0) stop_meas(&ru->rx_fhaul); proc->tti_tx = slot_tx; proc->frame_tx = frame_tx; @@ -605,7 +603,7 @@ void fh_if4p5_north_out(RU_t *ru) { stop_meas(&ru->tx_fhaul); } -static void *emulatedRF_thread(void *param) { +void *emulatedRF_thread(void *param) { RU_proc_t *proc = (RU_proc_t *) param; int microsec = 500; // length of time to sleep, in miliseconds struct timespec req = {0}; @@ -653,6 +651,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { ru->nb_rx); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); proc->timestamp_rx = ts-ru->ts_offset; @@ -674,9 +673,6 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*fp->slots_per_frame))&1023; proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame; // synchronize first reception to frame 0 subframe 0 - proc->timestamp_tx = proc->timestamp_rx+(sl_ahead*fp->samples_per_slot); - proc->tti_tx = (proc->tti_rx+sl_ahead)%fp->slots_per_frame; - proc->frame_tx = (proc->tti_rx>(fp->slots_per_frame-1-sl_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, 0, @@ -718,71 +714,74 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; void *txp[ru->nb_tx]; unsigned int txs; - int i; + int i,txsymb; T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot), T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4)); - int slot_type = nr_slot_select(ru->nr_frame_parms,frame,slot%fp->slots_per_frame); - int sf_extension = 0; - if ((slot_type & NR_UPLINK_SLOT) == 0) { + int slot_type = nr_slot_select(cfg,frame,slot%((1<ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)); + int prevslot_type = nr_slot_select(cfg,frame,(slot+(((1<ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)-1))%((1<ssb_config.scs_common.value)*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)); + int sf_extension = 0; //sf_extension = ru->sf_extension; + int siglen=fp->samples_per_slot; + int flags=1; - int siglen=fp->samples_per_slot,flags=1; - /* - if (SF_type == SF_S) { - siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); - flags=3; // end of burst - } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_DL)) { - flags = 2; // start of burst - sf_extension = ru->N_TA_offset<<1; - } + //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); + if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) { - if ((cfg->subframe_config.duplex_mode == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_UL)) { - flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = ru->N_TA_offset<<1; - } */ + if(slot_type == NR_MIXED_SLOT) { + txsymb = 0; + for(int symbol_count =0;symbol_counttdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) + txsymb++; + } + AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + //+ ru->end_of_burst_delay; + flags=3; // end of burst + } + + if (cfg->cell_config.frame_duplex_type.value == TDD && + slot_type == NR_DOWNLINK_SLOT && + prevslot_type == NR_UPLINK_SLOT) { + flags = 2; // start of burst + } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); - for (i=0; inb_tx; i++) txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - // prepare tx buffer pointers - txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); - LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); + // prepare tx buffer pointers + txs = ru->rfdevice.trx_write_func(&ru->rfdevice, + timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + txp, + siglen+sf_extension, + ru->nb_tx, + flags); + LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx, + (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); + AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); } } + /*! * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU. * This handles the RX FH for an asynchronous RRU/UE * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *ru_thread_asynch_rxtx( void *param ) { +void *ru_thread_asynch_rxtx( void *param ) { static int ru_thread_asynch_rxtx_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; int slot=0, frame=0; // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe wait_sync("ru_thread_asynch_rxtx"); @@ -806,7 +805,7 @@ static void *ru_thread_asynch_rxtx( void *param ) { // asynchronous receive from north (RRU IF4/IF5) if (ru->fh_north_asynch_in) { - if ((nr_slot_select(ru->nr_frame_parms,frame,slot) & NR_DOWNLINK_SLOT)>0) + if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0) ru->fh_north_asynch_in(ru,&frame,&slot); } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); } @@ -823,7 +822,7 @@ static void *ru_thread_asynch_rxtx( void *param ) { * \param param is a \ref RU_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *ru_thread_prach( void *param ) { +void *ru_thread_prach( void *param ) { static int ru_thread_prach_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = (RU_proc_t *)&ru->proc; @@ -859,7 +858,7 @@ static void *ru_thread_prach( void *param ) { 0,0 ); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/ if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; } @@ -993,7 +992,7 @@ void wakeup_gNB_L1s(RU_t *ru) { } } -static inline int wakeup_prach_ru(RU_t *ru) { +int wakeup_prach_ru(RU_t *ru) { struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -1028,10 +1027,10 @@ static inline int wakeup_prach_ru(RU_t *ru) { void fill_rf_config(RU_t *ru, char *rf_config_file) { int i; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index openair0_config_t *cfg = &ru->openair0_cfg; - int N_RB = gNB_config->rf_config.dl_carrier_bandwidth.value; - int mu = gNB_config->subframe_config.numerology_index_mu.value; + int mu = gNB_config->ssb_config.scs_common.value; + int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; if (mu == NR_MU_0) { //or if LTE if(N_RB == 100) { @@ -1104,7 +1103,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); } - if (gNB_config->subframe_config.duplex_mode.value==TDD) + if (gNB_config->cell_config.frame_duplex_type.value==TDD) cfg->duplex_mode = duplex_mode_TDD; else //FDD cfg->duplex_mode = duplex_mode_FDD; @@ -1188,7 +1187,7 @@ int setup_RU_buffers(RU_t *ru) { return(0); } -static void *ru_stats_thread(void *param) { +void *ru_stats_thread(void *param) { RU_t *ru = (RU_t *)param; wait_sync("ru_stats_thread"); @@ -1196,14 +1195,20 @@ static void *ru_stats_thread(void *param) { sleep(1); if (opp_enabled == 1) { + if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); - if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + if (ru->feptx_ofdm){ + print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL); + print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL); + print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + print_meas(&ru->ofdm_total_stats,"feptx_total",NULL,NULL); + } if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); - if (ru->fh_north_out) { print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); + if (ru->fh_north_out) { print_meas(&ru->compression,"compression",NULL,NULL); print_meas(&ru->transport,"transport",NULL,NULL); } @@ -1213,13 +1218,13 @@ static void *ru_stats_thread(void *param) { return(NULL); } -static void *ru_thread_tx( void *param ) { - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - PHY_VARS_gNB *gNB; - gNB_L1_proc_t *gNB_proc; +void *ru_thread_tx( void *param ) { + RU_t *ru = (RU_t *)param; + RU_proc_t *proc = &ru->proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + PHY_VARS_gNB *gNB; + gNB_L1_proc_t *gNB_proc; gNB_L1_rxtx_proc_t *L1_proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; char filename[40]; int print_frame = 8; int i = 0; @@ -1243,12 +1248,14 @@ static void *ru_thread_tx( void *param ) { // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx"); - AssertFatal((ret=pthread_mutex_lock(&proc->mutex_gNBs))==0,"mutex_lock return %d\n",ret); + ret = pthread_mutex_lock(&proc->mutex_gNBs); + AssertFatal(ret == 0,"mutex_lock return %d\n",ret); int frame_tx=proc->frame_tx; int tti_tx =proc->tti_tx; uint64_t timestamp_tx = proc->timestamp_tx; - AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_gNBs))==0,"mutex_lock returns %d\n",ret); + ret = pthread_mutex_unlock(&proc->mutex_gNBs); + AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); if (oai_exit) break; @@ -1258,7 +1265,7 @@ static void *ru_thread_tx( void *param ) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx); - // do OFDM if needed + // do OFDM with/without TX front-end processing if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx); if(!emulate_rf) { @@ -1269,8 +1276,17 @@ static void *ru_thread_tx( void *param ) { } else { if(proc->frame_tx == print_frame) { for (i=0; inb_tx; i++) { - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + + if(proc->tti_tx == 0) { + sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + } if(proc->tti_tx == 9) { sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); @@ -1299,7 +1315,8 @@ static void *ru_thread_tx( void *param ) { gNB = ru->gNB_list[i]; gNB_proc = &gNB->proc; L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc; - AssertFatal((ret=pthread_mutex_lock(&gNB_proc->mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); + ret = pthread_mutex_lock(&gNB_proc->mutex_RU_tx); + AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); for (int j=0; jnum_RU; j++) { if (ru == gNB->RU_list[j]) { @@ -1312,21 +1329,24 @@ static void *ru_thread_tx( void *param ) { } if (gNB_proc->RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return - AssertFatal((ret=pthread_mutex_unlock(&gNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); + AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); } else { // all RUs TX are finished so send the ready signal to gNB processing gNB_proc->RU_mask_tx = 0; - AssertFatal((ret=pthread_mutex_unlock(&gNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); + ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx); + AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret); + ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx); + AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); // the thread can now be woken up - if (L1_proc->instance_cnt_RUs==-1) { - AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, + //if (L1_proc->instance_cnt_RUs == -1) { + L1_proc->instance_cnt_RUs = 0; + AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, "ERROR pthread_cond_signal for gNB_L1_thread\n"); - } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); - L1_proc->instance_cnt_RUs = 0; + //} //else AssertFatal(1==0,"gNB TX thread is not ready\n"); + ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx); + AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); - AssertFatal((ret=pthread_mutex_unlock(&L1_proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret); - } } } @@ -1335,17 +1355,19 @@ static void *ru_thread_tx( void *param ) { return 0; } -static void *ru_thread( void *param ) { +void *ru_thread( void *param ) { static int ru_thread_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; int ret; - int slot = fp->slots_per_frame-1; - int frame =1023; - char filename[40],threadname[40]; + int slot = fp->slots_per_frame-1; + int frame = 1023; + char filename[40], threadname[40]; int print_frame = 8; int i = 0; + int aa; + // set default return value ru_thread_status = 0; // set default return value @@ -1377,9 +1399,9 @@ static void *ru_thread( void *param ) { } if (ru->if_south == LOCAL_RF) { // configure RF parameters only - fill_rf_config(ru,ru->rf_config_file); nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp); nr_dump_frame_parms(fp); + fill_rf_config(ru,ru->rf_config_file); nr_phy_init_RU(ru); ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); AssertFatal(ret==0,"Cannot connect to local radio\n"); @@ -1438,6 +1460,7 @@ static void *ru_thread( void *param ) { } // synchronization on input FH interface, acquire signals/data and block + LOG_D(PHY,"[RU_thread] read data: frame_rx = %d, tti_rx = %d\n", frame, slot); if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot); else AssertFatal(1==0, "No fronthaul interface at south port"); @@ -1462,7 +1485,19 @@ static void *ru_thread( void *param ) { if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; // do RX front-end processing (frequency-shift, dft) if needed - if (ru->feprx) ru->feprx(ru,proc->tti_rx); + + if (proc->tti_rx == NR_UPLINK_SLOT || fp->frame_type == FDD) { + + if (ru->feprx) ru->feprx(ru,proc->tti_rx); + + } + + LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx); + LOG_D(PHY,"Copying rxdataF from RU to gNB\n"); + + for (aa=0;aanb_rx;aa++) + memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa], + (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t)); // At this point, all information for subframe has been received on FH interface @@ -1473,7 +1508,7 @@ static void *ru_thread( void *param ) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); - // do OFDM if needed + // do OFDM with/without TX front-end processing if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); if(!emulate_rf) { @@ -1612,13 +1647,6 @@ int stop_rf(RU_t *ru) { return 0; } -extern void fep_full(RU_t *ru,int slot); -extern void ru_fep_full_2thread(RU_t *ru,int slot); -extern void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); -extern void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); -extern void feptx_prec(RU_t *ru, int frame_tx,int tti_tx); -extern void init_fep_thread(RU_t *ru); -extern void nr_init_feptx_thread(RU_t *ru); void init_RU_proc(RU_t *ru) { int i=0; @@ -1631,7 +1659,7 @@ void init_RU_proc(RU_t *ru) { memset((void *)proc,0,sizeof(RU_proc_t)); proc->ru = ru; proc->instance_cnt_prach = -1; - proc->instance_cnt_synch = -1; ; + proc->instance_cnt_synch = -1; proc->instance_cnt_FH = -1; proc->instance_cnt_FH1 = -1; proc->instance_cnt_gNBs = -1; @@ -1642,6 +1670,7 @@ void init_RU_proc(RU_t *ru) { proc->frame_offset = 0; proc->num_slaves = 0; proc->frame_tx_unwrap = 0; + proc->feptx_mask = 0; for (i=0; i<10; i++) proc->symbol_mask[i]=0; @@ -1684,7 +1713,7 @@ void init_RU_proc(RU_t *ru) { } if (get_thread_worker_conf() == WORKER_ENABLE) { - if (ru->feprx) init_fep_thread(ru); + if (ru->feprx) nr_init_feprx_thread(ru); if (ru->feptx_ofdm) nr_init_feptx_thread(ru); } @@ -1838,14 +1867,14 @@ void configure_ru(int idx, RU_t *ru = RC.ru[idx]; RRU_config_t *config = (RRU_config_t *)arg; RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; int ret; LOG_I(PHY, "Received capabilities from RRU %d\n",idx); if (capabilities->FH_fmt < MAX_FH_FMTs) LOG_I(PHY, "RU FH options %s\n",rru_format_options[capabilities->FH_fmt]); - AssertFatal((ret=check_capabilities(ru,capabilities)) == 0, - "Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret); + ret = check_capabilities(ru,capabilities); + AssertFatal(ret == 0, "Cannot configure RRU %d, check_capabilities returned %d\n", idx, ret); // take antenna capabilities of RRU ru->nb_tx = capabilities->nb_tx[0]; ru->nb_rx = capabilities->nb_rx[0]; @@ -1861,8 +1890,8 @@ void configure_ru(int idx, //config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S; config->att_tx[0] = ru->att_tx; config->att_rx[0] = ru->att_rx; - config->N_RB_DL[0] = gNB_config->rf_config.dl_carrier_bandwidth.value; - config->N_RB_UL[0] = gNB_config->rf_config.ul_carrier_bandwidth.value; + config->N_RB_DL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; + config->N_RB_UL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs; /* if (ru->if_south==REMOTE_IF4p5) { config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; @@ -1877,22 +1906,23 @@ void configure_rru(int idx, void *arg) { RRU_config_t *config = (RRU_config_t *)arg; RU_t *ru = RC.ru[idx]; - nfapi_nr_config_request_t *gNB_config = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; ru->nr_frame_parms->eutra_band = config->band_list[0]; ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0]; ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0]; if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) { - gNB_config->subframe_config.duplex_mode.value = TDD; + gNB_config->cell_config.frame_duplex_type.value = TDD; //ru->nr_frame_parms->tdd_config = config->tdd_config[0]; //ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0]; } else - gNB_config->subframe_config.duplex_mode.value = FDD; + gNB_config->cell_config.frame_duplex_type.value = FDD; ru->att_tx = config->att_tx[0]; ru->att_rx = config->att_rx[0]; - gNB_config->rf_config.dl_carrier_bandwidth.value = config->N_RB_DL[0]; - gNB_config->rf_config.ul_carrier_bandwidth.value = config->N_RB_UL[0]; + int mu = gNB_config->ssb_config.scs_common.value; + gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0]; + gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0]; ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0]; //ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0]; @@ -1977,8 +2007,8 @@ void set_function_spec_param(RU_t *ru) { ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception ru->fh_south_out = tx_rf; // send output to RF ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU) + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU) ru->feptx_prec = NULL; ru->nr_start_if = nr_start_if; // need to start the if interface for if4p5 ru->ifdevice.host_type = RRU_HOST; @@ -1999,9 +2029,9 @@ void set_function_spec_param(RU_t *ru) { malloc_IF4p5_buffer(ru); } else if (ru->function == gNodeB_3GPP) { ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; // RX DFTs + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding - ru->feptx_prec = NULL; // this is fep with idft and precoding + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // this is fep with idft and precoding ru->fh_north_in = NULL; // no incoming fronthaul from north ru->fh_north_out = NULL; // no outgoing fronthaul to north ru->nr_start_if = NULL; // no if interface @@ -2029,13 +2059,13 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF5: // the remote unit is IF5 RRU ru->do_prach = 0; - ru->feprx = fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs - ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission - ru->fh_south_asynch_in = NULL; // no asynchronous UL - ru->start_rf = NULL; // no local RF + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // this is frequency-shift + DFTs + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs + ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception + ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission + ru->fh_south_asynch_in = NULL; // no asynchronous UL + ru->start_rf = NULL; // no local RF ru->stop_rf = NULL; ru->nr_start_if = nr_start_if; // need to start if interface for IF5 ru->ifdevice.host_type = RAU_HOST; @@ -2054,7 +2084,7 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF4p5: ru->do_prach = 0; ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // Precoding operation ru->feptx_ofdm = NULL; // no OFDM mod ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission @@ -2084,12 +2114,11 @@ void set_function_spec_param(RU_t *ru) { } // switch on interface type } -extern void RCconfig_RU(void); - void init_NR_RU(char *rf_config_file) { int ru_id; RU_t *ru; + PHY_VARS_gNB *gNB_RC; PHY_VARS_gNB *gNB0= (PHY_VARS_gNB *)NULL; NR_DL_FRAME_PARMS *fp = (NR_DL_FRAME_PARMS *)NULL; int i; @@ -2129,6 +2158,7 @@ void init_NR_RU(char *rf_config_file) } } + gNB_RC = RC.gNB[0]; gNB0 = ru->gNB_list[0]; fp = ru->nr_frame_parms; LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); @@ -2137,10 +2167,11 @@ void init_NR_RU(char *rf_config_file) if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) AssertFatal(gNB0!=NULL,"gNB0 is null!\n"); - if (gNB0) { - LOG_I(PHY,"Copying frame parms from gNB %d to ru %d\n",gNB0->Mod_id,ru->idx); - memcpy((void *)fp,(void *)&gNB0->frame_parms,sizeof(NR_DL_FRAME_PARMS)); - memset((void *)ru->frame_parms, 0, sizeof(LTE_DL_FRAME_PARMS)); + if (gNB0 && gNB_RC) { + LOG_I(PHY,"Copying frame parms from gNB in RC to gNB %d in ru %d and frame_parms in ru\n",gNB0->Mod_id,ru->idx); + memset((void *)fp, 0, sizeof(NR_DL_FRAME_PARMS)); + memcpy((void *)fp,&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS)); + memcpy((void *)&gNB0->frame_parms,(void *)&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS)); // attach all RU to all gNBs in its list/ LOG_D(PHY,"ru->num_gNB:%d gNB0->num_RU:%d\n", ru->num_gNB, gNB0->num_RU); @@ -2219,6 +2250,9 @@ void RCconfig_RU(void) LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); } } + else { + RC.ru[j]->openair0_cfg.clock_source = unset; + } if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { @@ -2296,6 +2330,14 @@ void RCconfig_RU(void) RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); + + if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { + RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; + for (i=0; inum_gNB; i++) { + RC.ru[j]->bw_list[i] = (int32_t *)malloc16_clear((RC.ru[j]->nb_bfw)*sizeof(int32_t)); + for (int b=0; bnb_bfw; b++) RC.ru[j]->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; + } + } }// j=0..num_rus } else { RC.nb_RU = 0; @@ -2303,3 +2345,4 @@ void RCconfig_RU(void) return; } + diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 0fec975e6f..c9d0930e83 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -1,7 +1,7 @@ #ifndef NR_SOFTMODEM_COMMON_H #define NR_SOFTMODEM_COMMON_H -#ifndef _GNU_SOURCE +#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -83,6 +83,7 @@ #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_DISABLETIMECORR "disable UE timing correction\n" +#define CONFIG_HLP_RRC_CFG_PATH "path for RRC configuration\n" #define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" #define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" @@ -98,6 +99,8 @@ #define CONFIG_HLP_TELN "Start embedded telnet server \n" #define CONFIG_HLP_MSC "Enable the MSC tracing utility \n" #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" +#define CONFIG_HLP_NOS1 "Disable s1 interface\n" +#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" /*--------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters for LOG utility */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 00865f8799..61d6362e9e 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -83,6 +83,8 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "PHY/TOOLS/nr_phy_scope.h" #include "stats.h" #include "nr-softmodem.h" +#include "executables/softmodem-common.h" +#include "executables/thread-common.h" #include "NB_IoT_interface.h" #include "x2ap_eNB.h" @@ -105,7 +107,6 @@ int config_sync_var=-1; #endif volatile int oai_exit = 0; -static clock_source_t clock_source = internal; static int wait_for_sync = 0; unsigned int mmapped_dma=0; @@ -168,7 +169,7 @@ int rx_input_level_dBm; uint32_t do_forms=0; int otg_enabled; -//int number_of_cards = 1; +//int number_of_cards = 1; //static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; @@ -189,46 +190,10 @@ int transmission_mode=1; int emulate_rf = 0; int numerology = 0; -typedef struct { - uint64_t optmask; - THREAD_STRUCT thread_struct; - char rf_config_file[1024]; - int phy_test; - uint8_t usim_test; - int emulate_rf; - int wait_for_sync; //eNodeB only - int single_thread_flag; //eNodeB only - int chain_offset; - int numerology; - unsigned int start_msc; - uint32_t clock_source; - int hw_timing_advance; -} softmodem_params_t; static softmodem_params_t softmodem_params; static char *parallel_config = NULL; static char *worker_config = NULL; -static THREAD_STRUCT thread_struct; - -void set_parallel_conf(char *parallel_conf) { - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) { - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) { - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) { - return thread_struct.worker_conf; -} /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; @@ -246,7 +211,7 @@ char uecap_xer_in=0; uint8_t abstraction_flag=0; /* forward declarations */ -void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); +void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); /*---------------------BMC: timespec helpers -----------------------------*/ @@ -520,7 +485,9 @@ static void get_options(void) { int tddflag, nonbiotflag; uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; - uint32_t start_telnetsrv; + uint32_t start_telnetsrv = 0; + uint32_t noS1; + uint32_t nokrnmod; paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; paramdef_t cmdline_logparams[] = CMDLINE_LOGPARAMS_DESC_NR ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); @@ -558,6 +525,7 @@ static void get_options(void) { if(parallel_config != NULL) set_parallel_conf(parallel_config); if(worker_config != NULL) set_worker_conf(worker_config); + } @@ -569,18 +537,18 @@ static void get_options(void) { -void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], - NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) +void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], + NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { for (int CC_id=0; CC_idsubframe_config.numerology_index_mu.value =1; - config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD - config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL - config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106; - config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106; - config[CC_id]->sch_config.physical_cell_id.value = 0; + config[CC_id] = (nfapi_nr_config_request_scf_t *) malloc(sizeof(nfapi_nr_config_request_scf_t)); + config[CC_id]->ssb_config.scs_common.value = 1; + config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD + //config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL + config[CC_id]->carrier_config.dl_grid_size[1].value = 106; + config[CC_id]->carrier_config.ul_grid_size[1].value = 106; + config[CC_id]->cell_config.phy_cell_id.value = 0; ///dl frequency to be filled in /* //Set some default values that may be overwritten while reading options frame_parms[CC_id]->frame_type = FDD; @@ -873,6 +841,30 @@ static void wait_nfapi_init(char *thread_name) { printf( "NFAPI: got sync (%s)\n", thread_name); } +void init_pdcp(void) { + //if (!NODE_IS_DU(RC.rrc[0]->node_type)) { + pdcp_layer_init(); + uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? + (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; + + if (IS_SOFTMODEM_NOS1){ + printf("IS_SOFTMODEM_NOS1 option enabled \n"); + pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; + } + + pdcp_module_init(pdcp_initmask); + + /*if (NODE_IS_CU(RC.rrc[0]->node_type)) { + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req); + } else {*/ + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); + //} + /*} else { + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind); + }*/ +} + int main( int argc, char **argv ) { int i, ru_id, CC_id = 0; @@ -894,6 +886,7 @@ int main( int argc, char **argv ) configure_linux(); printf("Reading in command-line options\n"); get_options (); + get_common_options(); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); @@ -939,6 +932,9 @@ init_opt(); #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + if(IS_SOFTMODEM_NOS1) + init_pdcp(); + if (RC.nb_nr_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP @@ -958,6 +954,7 @@ init_opt(); flexran_agent_start(i); } */ + // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 50e0c5469f..8334c99134 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -5,25 +5,24 @@ #include "flexran_agent.h" #include "PHY/defs_gNB.h" +#include "proto_agent.h" #define DEFAULT_DLF 2680000000 - /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument when calling config_get or config_getlist functions */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters common to eNodeB and UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_GNB { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ - {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ @@ -42,14 +41,21 @@ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ - {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ + {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ + {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ + {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0} \ } +#define SOFTMODEM_NOS1_BIT (1<<0) +#define SOFTMODEM_NOKRNMOD_BIT (1<<1) +#define SOFTMODEM_RFSIM_BIT (1<<10) -typedef struct { - int *argc; - char **argv; -} scopeParms_t; +#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) +#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) + +#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) +extern uint64_t get_softmodem_optmask(void); +extern void get_common_options(void); extern int T_port; extern int T_nowait; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f2115fc6ea..79ea205680 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -45,6 +45,7 @@ #include "common/utils/LOG/log.h" #include "common/utils/system.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "executables/nr-softmodem.h" #include "T.h" @@ -141,8 +142,10 @@ PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE)); memset(ue,0,sizeof(PHY_VARS_NR_UE)); memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS)); + ue->Mod_id = UE_id; ue->mac_enabled = 1; + // initialize all signal buffers init_nr_ue_signal(ue,1,abstraction_flag); // intialize transport @@ -353,6 +356,9 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { nr_dcireq_t dcireq; nr_scheduled_response_t scheduled_response; + uint32_t nb_rb, start_rb; + uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx; + uint16_t n_rnti; // Process Rx data for one sub-frame if (nr_slot_select(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) { @@ -365,22 +371,57 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { nr_ue_dcireq(&dcireq); //to be replaced with function pointer later scheduled_response.dl_config = &dcireq.dl_config_req; - scheduled_response.ul_config = NULL; + scheduled_response.ul_config = &dcireq.ul_config_req; scheduled_response.tx_request = NULL; scheduled_response.module_id = UE->Mod_id; scheduled_response.CC_id = 0; scheduled_response.frame = proc->frame_rx; scheduled_response.slot = proc->nr_tti_rx; + + //--------------------------Temporary configuration-----------------------------// + n_rnti = 0x1234; + nb_rb = 50; + start_rb = 0; + nb_symb_sch = 12; + start_symbol = 2; + precod_nbr_layers = 1; + mcs = 9; + harq_pid = 0; + rvidx = 0; + //------------------------------------------------------------------------------// + + scheduled_response.ul_config->sfn_slot = NR_UPLINK_SLOT; + 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].ulsch_config_pdu.rnti = n_rnti; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = mcs; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = rvidx; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers; + scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid; nr_ue_scheduled_response(&scheduled_response); #ifdef UE_SLOT_PARALLELISATION 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, scheduled_response.dl_config); + phy_procedures_nrUE_RX( UE, proc, 0, 1, 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 + if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1 + //Hardcoded rnti value + protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, + 0x1234, proc->frame_rx, + proc->nr_tti_rx, 0); + pdcp_run(&ctxt); + pdcp_fifo_flush_sdus(&ctxt); + } } @@ -415,13 +456,14 @@ typedef struct processingData_s { } processingData_t; void UE_processing(void *arg) { + uint8_t thread_id; processingData_t *rxtxD=(processingData_t *) arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; processSlotRX(UE, proc); //printf(">>> mac ended\n"); // Prepare the future Tx data -#if 0 +/* #ifndef NO_RAT_NR if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT) @@ -429,11 +471,21 @@ void UE_processing(void *arg) { if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || (UE->frame_parms.frame_type == FDD) ) #endif +*/ + + + if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD){ + + thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx]; + + if (UE->mode != loop_through_memory) - phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay); + phy_procedures_nrUE_TX(UE,proc,0,thread_id); + + } //phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); -#endif + #if 0 if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && @@ -486,6 +538,9 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { dummy_rx, UE->frame_parms.samples_per_subframe, UE->frame_parms.nb_antennas_rx); + if (IS_SOFTMODEM_RFSIM ) { + usleep(1000); // slow down, as would do actuall rf to let cpu for the synchro thread + } } for (int i=0; iframe_parms.nb_antennas_tx; i++) @@ -643,12 +698,12 @@ void *UE_thread(void *arg) { //LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB); #ifdef OAI_ADRV9371_ZC706 - uint32_t total_gain_dB_prev = 0; + /*uint32_t total_gain_dB_prev = 0; if (total_gain_dB_prev != UE->rx_total_gain_dB) { total_gain_dB_prev = UE->rx_total_gain_dB; - openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB-20; + openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB; UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]); - } + }*/ #endif for (int i=0; iframe_parms.nb_antennas_rx; i++) @@ -657,7 +712,7 @@ void *UE_thread(void *arg) { slot_nr*UE->frame_parms.samples_per_slot]; for (int i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void *)&UE->common_vars.txdata[i][curMsg->proc.nr_tti_tx*UE->frame_parms.samples_per_slot]; + txp[i] = (void *)&UE->common_vars.txdata[i][((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame)*UE->frame_parms.samples_per_slot]; int readBlockSize, writeBlockSize; @@ -680,16 +735,18 @@ void *UE_thread(void *arg) { rxp, readBlockSize, UE->frame_parms.nb_antennas_rx),""); + +if (slot_nr==18) AssertFatal( writeBlockSize == UE->rfdevice.trx_write_func(&UE->rfdevice, timestamp+ - (2*UE->frame_parms.samples_per_slot) - + (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - openair0_cfg[0].tx_sample_advance, txp, writeBlockSize, UE->frame_parms.nb_antennas_tx, - 1),""); + 4),""); if( slot_nr==(nb_slot_frame-1)) { // read in first symbol of next frame and adjust for timing drift @@ -734,7 +791,7 @@ void *UE_thread(void *arg) { msgToPush->key=slot_nr; pushTpool(Tpool, msgToPush); - if (getenv("RFSIMULATOR")) { + if (getenv("RFSIMULATOR") || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR") // FixMe: Wait previous thread is done, because race conditions seems too bad // in case of actual RF board, the overlap between threads mitigate the issue // We must receive one message, that proves the slot processing is done @@ -752,7 +809,7 @@ void *UE_thread(void *arg) { return NULL; } -void init_NR_UE(int nb_inst) { +void init_NR_UE(int nb_inst, char* rrc_config_path) { int inst; NR_UE_MAC_INST_t *mac_inst; pthread_t threads[nb_inst]; @@ -760,21 +817,10 @@ void init_NR_UE(int nb_inst) { for (inst=0; inst < nb_inst; inst++) { PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n"); - nr_l3_init_ue(); + nr_l3_init_ue(rrc_config_path); nr_l2_init_ue(); mac_inst = get_mac_inst(inst); mac_inst->if_module = UE->if_inst; - // Initial bandwidth part configuration -- full carrier bandwidth - mac_inst->initial_bwp_dl.bwp_id = 0; - mac_inst->initial_bwp_dl.location = 0; - mac_inst->initial_bwp_dl.scs = UE->frame_parms.subcarrier_spacing; - mac_inst->initial_bwp_dl.N_RB = UE->frame_parms.N_RB_DL; - mac_inst->initial_bwp_dl.cyclic_prefix = UE->frame_parms.Ncp; - mac_inst->initial_bwp_ul.bwp_id = 0; - mac_inst->initial_bwp_ul.location = 0; - mac_inst->initial_bwp_ul.scs = UE->frame_parms.subcarrier_spacing; - mac_inst->initial_bwp_ul.N_RB = UE->frame_parms.N_RB_UL; - mac_inst->initial_bwp_ul.cyclic_prefix = UE->frame_parms.Ncp; LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 9a4a0cdf70..e535040fa9 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -29,6 +29,7 @@ #include "PHY/defs_nr_UE.h" #include "common/ran_context.h" #include "common/config/config_userapi.h" +//#include "common/utils/threadPool/thread-pool.h" #include "common/utils/load_module_shlib.h" //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -77,9 +78,11 @@ unsigned short config_frames[4] = {2,9,11,13}; #include + /* Callbacks, globals and object handlers */ extern void reset_stats( FL_OBJECT *, long ); +//extern void initTpool(char *params,tpool_t *pool, bool performanceMeas); /* Forms and Objects */ @@ -102,16 +105,18 @@ FD_phy_scope_nrue *form_nrue[NUMBER_OF_UE_MAX]; //FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; char title[255]; -static pthread_t forms_thread; //xforms +static pthread_t forms_thread; //xforms #include +#include "executables/softmodem-common.h" +#include "executables/thread-common.h" RAN_CONTEXT_t RC; volatile int start_eNB = 0; volatile int start_UE = 0; volatile int oai_exit = 0; -static clock_source_t clock_source = internal; +static clock_source_t clock_source = unset; int single_thread_flag=1; static double snr_dB=20; @@ -147,7 +152,7 @@ double bw = 10.0e6; static int tx_max_power[MAX_NUM_CCs] = {0}; -char rf_config_file[1024]; +char rf_config_file[1024]; int chain_offset=0; int phy_test = 0; @@ -162,53 +167,18 @@ uint8_t nb_antenna_rx = 1; char ref[128] = "internal"; char channels[128] = "0"; -typedef struct { - uint64_t optmask; - THREAD_STRUCT thread_struct; - char rf_config_file[1024]; - int phy_test; - uint8_t usim_test; - int emulate_rf; - int wait_for_sync; //eNodeB only - int single_thread_flag; //eNodeB only - int chain_offset; - int numerology; - unsigned int start_msc; - uint32_t clock_source; - int hw_timing_advance; -} softmodem_params_t; static softmodem_params_t softmodem_params; static char *parallel_config = NULL; static char *worker_config = NULL; -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) { - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) { - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) { - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) { - return thread_struct.worker_conf; -} int rx_input_level_dBm; //static int online_log_messages=0; uint32_t do_forms=0; int otg_enabled; -//int number_of_cards = 1; +//int number_of_cards = 1; static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; int16_t node_synch_ref[MAX_NUM_CCs]; @@ -239,6 +209,8 @@ tpool_t *Tpool; char *usrp_args=NULL; +char *rrc_config_path=NULL; + /* forward declarations */ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); @@ -404,6 +376,8 @@ static void get_options(void) { uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; uint32_t start_telnetsrv=0; + //uint32_t noS1; + //uint32_t nokrnmod; paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC_NR ; config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); @@ -549,14 +523,23 @@ void init_openair0(void) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=92.16e6; openair0_cfg[card].samples_per_frame = 921600; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; } else { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; + } + } else { + LOG_E(PHY,"Unsupported numerology!\n"); + exit(-1); + } + }else if(frame_parms[0]->N_RB_DL == 273) { + if (numerology==1) { + if (frame_parms[0]->threequarter_fs) { + AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); + } + else { + openair0_cfg[card].sample_rate=122.88e6; + openair0_cfg[card].samples_per_frame = 1228800; } } else { LOG_E(PHY,"Unsupported numerology!\n"); @@ -567,32 +550,22 @@ void init_openair0(void) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; } else { openair0_cfg[card].sample_rate=30.72e6; openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; } } else if (numerology==1) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=46.08e6; openair0_cfg[card].samples_per_frame = 480800; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; } else { openair0_cfg[card].sample_rate=61.44e6; openair0_cfg[card].samples_per_frame = 614400; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; } } else if (numerology==2) { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; } else { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); @@ -600,18 +573,12 @@ void init_openair0(void) { } else if(frame_parms[0]->N_RB_DL == 50) { openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; } else if (frame_parms[0]->N_RB_DL == 25) { openair0_cfg[card].sample_rate=7.68e6; openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; } else if (frame_parms[0]->N_RB_DL == 6) { openair0_cfg[card].sample_rate=1.92e6; openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; } else { LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL); @@ -659,6 +626,27 @@ void init_openair0(void) { } } +void init_pdcp(void) { + uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); + + /*if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) { + pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; + }*/ + + if (IS_SOFTMODEM_NOKRNMOD) + pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; + + /*if (rlc_module_init() != 0) { + LOG_I(RLC, "Problem at RLC initiation \n"); + } + pdcp_layer_init(); + nr_ip_over_LTE_DRB_preconfiguration();*/ + pdcp_module_init(pdcp_initmask); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); + LOG_I(PDCP, "Before getting out from init_pdcp() \n"); +} + int main( int argc, char **argv ) { //uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; @@ -678,6 +666,7 @@ int main( int argc, char **argv ) { logInit(); // get options and fill parameters from configuration file get_options (); //Command-line options, enb_properties + get_common_options(); #if T_TRACER T_Config_Init(); #endif @@ -691,18 +680,22 @@ int main( int argc, char **argv ) { itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); init_opt() ; + if(IS_SOFTMODEM_NOS1) + init_pdcp(); if (ouput_vcd) { vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd"); } +/* #ifdef PDCP_USE_NETLINK netlink_init(); #if defined(PDCP_USE_NETLINK_QUEUES) pdcp_netlink_init(); #endif #endif -#ifndef PACKAGE_VERSION +*/ + #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); @@ -728,10 +721,7 @@ int main( int argc, char **argv ) { PHY_vars_UE_g[0][CC_id] = init_nr_ue_vars(frame_parms[CC_id], 0,abstraction_flag); UE[CC_id] = PHY_vars_UE_g[0][CC_id]; - if (phy_test==1) - UE[CC_id]->mac_enabled = 0; - else - UE[CC_id]->mac_enabled = 1; + UE[CC_id]->mac_enabled = 1; UE[CC_id]->UE_scan = UE_scan; UE[CC_id]->UE_scan_carrier = UE_scan_carrier; @@ -740,13 +730,6 @@ int main( int argc, char **argv ) { UE[CC_id]->no_timing_correction = UE_no_timing_correction; printf("UE[%d]->mode = %d\n",CC_id,mode); - for (uint8_t i=0; imac_enabled == 1) - UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1234; - else - UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1235; - } - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; @@ -777,6 +760,7 @@ int main( int argc, char **argv ) { PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; #if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706) PHY_vars_UE_g[0][CC_id]->hw_timing_advance = timing_advance; + PHY_vars_UE_g[0][CC_id]->timing_advance = timing_advance; #else PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160; #endif @@ -784,7 +768,7 @@ int main( int argc, char **argv ) { // wait for end of program printf("TYPE TO TERMINATE\n"); - init_NR_UE(1); + init_NR_UE(1,rrc_config_path); while(true) sleep(3600); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 6dd00276ed..fe448cf28e 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -1,6 +1,7 @@ #ifndef NR_UESOFTMODEM_H #define NR_UESOFTMODEM_H #include +#include #include "PHY/defs_nr_UE.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" #include @@ -50,41 +51,42 @@ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ {"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ - {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \ + {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \ } #define DEFAULT_DLF 2680000000 -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters common to eNodeB and UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_UE { \ - {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ - {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ - {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ - {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ - {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ - {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ - {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ - {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ - {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ - {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ - {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \ - {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ - {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ - {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ - {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ - {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ - {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ - {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ - {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ - {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ - {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ - {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ - {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0} \ + {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\ + {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ + {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ + {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ + {"clock-source", CONFIG_HLP_EXCCLK, 0, iptr:&clock_source, defintval:0, TYPE_INT, 0}, \ + {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ + {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ + {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ + {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ + {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ + {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \ + {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ + {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ + {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ + {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ + {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ + {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ + {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ + {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ + {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ + {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ + {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ + {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \ + {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \ } @@ -94,15 +96,12 @@ extern int T_dont_fork; // In nr-ue.c -extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, - openair0_config_t *openair0_cfg); +extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); -extern void init_NR_UE(int); +extern void init_NR_UE(int, char*); extern void reset_opp_meas(void); extern void print_opp_meas(void); void *UE_thread(void *arg); -PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, - uint8_t UE_id, - uint8_t abstraction_flag); +PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); extern tpool_t *Tpool; #endif diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h new file mode 100644 index 0000000000..f6ba3a6beb --- /dev/null +++ b/executables/softmodem-common.h @@ -0,0 +1,22 @@ +#ifndef SOFTMODEM_COMMON_H +#define SOFTMODEM_COMMON_H + +typedef struct { + uint64_t optmask; + THREAD_STRUCT thread_struct; + char rf_config_file[1024]; + int phy_test; + uint8_t usim_test; + int emulate_rf; + int wait_for_sync; //eNodeB only + int single_thread_flag; //eNodeB only + int chain_offset; + int numerology; + unsigned int start_msc; + uint32_t clock_source; + uint32_t timing_source; + int hw_timing_advance; + uint32_t send_dmrs_sync; +} softmodem_params_t; + +#endif diff --git a/executables/thread-common.h b/executables/thread-common.h new file mode 100644 index 0000000000..6f3af3cfc0 --- /dev/null +++ b/executables/thread-common.h @@ -0,0 +1,42 @@ +#ifndef THREAD_COMMON_H +#define THREAD_COMMON_H + +#include "PHY/defs_common.h" + +THREAD_STRUCT thread_struct; + +static inline void set_parallel_conf(char *parallel_conf) { + mapping config[]= { + FOREACH_PARALLEL(GENERATE_ENUMTXT) + {NULL,-1} + }; + thread_struct.parallel_conf = (PARALLEL_CONF_t)map_str_to_int(config, parallel_conf); + if (thread_struct.parallel_conf == -1 ) { + LOG_E(ENB_APP,"Impossible value: %s\n", parallel_conf); + thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + } + printf("[CONFIG] parallel_conf is set to %d\n", thread_struct.parallel_conf); +} + +static inline void set_worker_conf(char *worker_conf) { + mapping config[]={ + FOREACH_WORKER(GENERATE_ENUMTXT) + {NULL, -1} + }; + thread_struct.worker_conf = (WORKER_CONF_t)map_str_to_int(config, worker_conf); + if (thread_struct.worker_conf == -1 ) { + LOG_E(ENB_APP,"Impossible value: %s\n", worker_conf); + thread_struct.worker_conf = WORKER_DISABLE ; + } + printf("[CONFIG] worker_conf is set to %d\n", thread_struct.worker_conf); +} + +static inline PARALLEL_CONF_t get_thread_parallel_conf(void) { + return thread_struct.parallel_conf; +} + +static inline WORKER_CONF_t get_thread_worker_conf(void) { + return thread_struct.worker_conf; +} + +#endif diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index a0574221f5..7ab8be5746 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -31,7 +31,7 @@ #include #include -#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "nfapi_vnf_interface.h" #include "nfapi.h" #include "vendor_ext.h" @@ -1169,7 +1169,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return retval; } -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) +int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; @@ -1177,9 +1177,9 @@ int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req); - dl_config_req->dl_config_request_body.number_dci = 0; - dl_config_req->dl_config_request_body.number_pdu = 0; - dl_config_req->dl_config_request_body.number_pdsch_rnti = 0; + dl_config_req->dl_tti_request_body.nPDUs = 0; + dl_config_req->dl_tti_request_body.nGroup = 0; + if (retval!=0) { LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index 32046d4982..cbcd26c3e3 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -8,6 +8,9 @@ #define FAPI_NR_MAX_NUM_ZP_CSI_RS_RESOURCE_PER_SET 16 #define FAPI_NR_MAX_NUM_CANDIDATE_BEAMS 16 #define FAPI_NR_MAX_RA_OCCASION_PER_CSIRS 64 +// Constants Defined in 38.213 +#define FAPI_NR_MAX_CORESET_PER_BWP 3 +#define FAPI_NR_MAX_SS_PER_CORESET 10 /// RX_IND @@ -41,8 +44,8 @@ #define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02 -#define CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 -#define CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 +#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 +#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 #define PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE 0x01 #define PRECODER_GRANULARITY_ALL_CONTIGUOUS_RBS 0x02 @@ -51,8 +54,8 @@ #define FAPI_NR_UL_CONFIG_LIST_NUM 10 #define FAPI_NR_UL_CONFIG_TYPE_PRACH 0x01 -#define FAPI_NR_UL_CONFIG_TYPE_UCI 0x02 -#define FAPI_NR_UL_CONFIG_TYPE_ULSCH 0x03 +#define FAPI_NR_UL_CONFIG_TYPE_PUCCH 0x02 +#define FAPI_NR_UL_CONFIG_TYPE_PUSCH 0x03 #define FAPI_NR_UL_CONFIG_TYPE_SRS 0x04 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 30020aaf23..c5b7a0a5ea 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -1,5 +1,4 @@ -/* - * Copyright 2017 Cisco Systems, Inc. +/*Copyright 2017 Cisco Systems, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,77 +31,7 @@ typedef signed char int8_t; */ -typedef struct { - uint8_t identifier_dci_formats ; // 0 IDENTIFIER_DCI_FORMATS: - uint8_t carrier_ind ; // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] - uint8_t sul_ind_0_1 ; // 2 SUL_IND_0_1: - uint8_t slot_format_ind ; // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] - uint8_t pre_emption_ind ; // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits - uint8_t block_number ; // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3 - uint8_t close_loop_ind ; // 6 CLOSE_LOOP_IND: - uint8_t bandwidth_part_ind ; // 7 BANDWIDTH_PART_IND: - uint8_t short_message_ind ; // 8 SHORT_MESSAGE_IND: - uint8_t short_messages ; // 9 SHORT_MESSAGES: - uint16_t freq_dom_resource_assignment_UL; // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - // (NOTE 1) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is larger than the payload size of the DCI format 1_0 monitored in common search space - // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 - // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0 - uint16_t freq_dom_resource_assignment_DL; // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - uint8_t time_dom_resource_assignment ; // 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - // where I the number of entries in the higher layer parameter pusch-AllocationList - uint8_t vrb_to_prb_mapping ; // 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - uint8_t prb_bundling_size_ind ; // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - uint8_t rate_matching_ind ; // 15 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set - uint8_t zp_csi_rs_trigger ; // 16 ZP_CSI_RS_TRIGGER: - uint8_t freq_hopping_flag ; // 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - uint8_t tb1_mcs ; // 18 TB1_MCS: - uint8_t tb1_ndi ; // 19 TB1_NDI: - uint8_t tb1_rv ; // 20 TB1_RV: - uint8_t tb2_mcs ; // 21 TB2_MCS: - uint8_t tb2_ndi ; // 22 TB2_NDI: - uint8_t tb2_rv ; // 23 TB2_RV: - uint8_t mcs ; // 24 MCS: - uint8_t ndi ; // 25 NDI: - uint8_t rv ; // 26 RV: - uint8_t harq_process_number ; // 27 HARQ_PROCESS_NUMBER: - uint8_t dai ; // 28 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI - // 0 otherwise - uint8_t first_dai ; // 29 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK - uint8_t second_dai ; // 30 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks - uint8_t tb_scaling ; // 31 TB_SCALING: - uint8_t tpc_pusch ; // 32 TPC_PUSCH: - uint8_t tpc_pucch ; // 33 TPC_PUCCH: - uint8_t pucch_resource_ind ; // 34 PUCCH_RESOURCE_IND: - uint8_t pdsch_to_harq_feedback_time_ind ; // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - uint8_t srs_resource_ind ; // 36 SRS_RESOURCE_IND: - uint8_t precod_nbr_layers ; // 37 PRECOD_NBR_LAYERS: - uint8_t antenna_ports ; // 38 ANTENNA_PORTS: - uint8_t tci ; // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits - uint8_t srs_request ; // 40 SRS_REQUEST: - uint8_t tpc_cmd ; // 41 TPC_CMD: - uint8_t csi_request ; // 42 CSI_REQUEST: - uint8_t cbgti ; // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH - uint8_t cbgfi ; // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator - uint8_t ptrs_dmrs ; // 45 PTRS_DMRS: - uint8_t beta_offset_ind ; // 46 BETA_OFFSET_IND: - uint8_t dmrs_seq_ini ; // 47 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding - // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise - uint8_t ul_sch_ind ; // 48 UL_SCH_IND: value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH - uint16_t padding_nr_dci ; // 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is less than the payload size of the DCI format 1_0 monitored in common search space - // zeros shall be appended to the DCI format 0_0 - // until the payload size equals that of the DCI format 1_0 - uint8_t sul_ind_0_0 ; // 50 SUL_IND_0_0: - uint8_t ra_preamble_index ; // 51 RA_PREAMBLE_INDEX: - uint8_t sul_ind_1_0 ; // 52 SUL_IND_1_0: - uint8_t ss_pbch_index ; // 53 SS_PBCH_INDEX - uint8_t prach_mask_index ; // 54 PRACH_MASK_INDEX - uint8_t reserved_nr_dci ; // 55 RESERVED_NR_DCI -} fapi_nr_dci_pdu_rel15_t; + @@ -121,16 +50,14 @@ typedef struct { typedef struct { /// frequency_domain_resource; - //uint32_t rb_start; - //uint32_t rb_end; - uint64_t frequency_domain_resource; - uint16_t rb_offset; - + uint8_t frequency_domain_resource[6]; + uint8_t StartSymbolIndex; uint8_t duration; - uint8_t cce_reg_mapping_type; // interleaved or noninterleaved - uint8_t cce_reg_interleaved_reg_bundle_size; // valid if CCE to REG mapping type is interleaved type - uint8_t cce_reg_interleaved_interleaver_size; // valid if CCE to REG mapping type is interleaved type - uint8_t cce_reg_interleaved_shift_index; // valid if CCE to REG mapping type is interleaved type + uint8_t CceRegMappingType; // interleaved or noninterleaved + uint8_t RegBundleSize; // valid if CCE to REG mapping type is interleaved type + uint8_t InterleaverSize; // valid if CCE to REG mapping type is interleaved type + uint8_t ShiftIndex; // valid if CCE to REG mapping type is interleaved type + uint8_t CoreSetType; uint8_t precoder_granularity; uint16_t pdcch_dmrs_scrambling_id; @@ -155,13 +82,16 @@ typedef struct { int n_CCE; // N_CCE is L, or number of CCEs for DCI int N_CCE; - fapi_nr_dci_pdu_rel15_t dci; + uint8_t payloadSize; + uint8_t payloadBits[16]; + //fapi_nr_dci_pdu_rel15_t dci; } fapi_nr_dci_indication_pdu_t; /// typedef struct { - uint32_t sfn_slot; + uint16_t SFN; + uint8_t slot; uint16_t number_of_dcis; fapi_nr_dci_indication_pdu_t dci_list[10]; } fapi_nr_dci_indication_t; @@ -197,11 +127,11 @@ typedef struct { } fapi_nr_rx_indication_body_t; /// -#define FAPI_RX_IND_MAX_PDU 100 +#define NFAPI_RX_IND_MAX_PDU 100 typedef struct { uint32_t sfn_slot; uint16_t number_pdus; - fapi_nr_rx_indication_body_t rx_indication_body[FAPI_RX_IND_MAX_PDU]; + fapi_nr_rx_indication_body_t rx_indication_body[NFAPI_RX_IND_MAX_PDU]; } fapi_nr_rx_indication_t; typedef struct { @@ -224,22 +154,22 @@ typedef struct { fapi_nr_tx_request_body_t *tx_request_body; } fapi_nr_tx_request_t; -typedef struct { - uint8_t preamble_index; - uint8_t prach_configuration_index; - uint16_t preamble_length; - uint8_t power_ramping_step; - uint16_t preamble_received_target_power; - uint8_t msg1_fdm; - uint8_t msg1_frequency_start; - uint8_t zero_correlation_zone_config; - uint8_t subcarrier_spacing; - uint8_t restrictedset_config; - uint16_t root_sequence_index; - uint16_t rsrp_threshold_ssb; - uint16_t rsrp_threshold_sul; - uint16_t prach_freq_offset; -} fapi_nr_ul_config_prach_pdu; + typedef struct { + uint8_t preamble_index; + uint8_t prach_configuration_index; + uint16_t preamble_length; + uint8_t power_ramping_step; + uint16_t preamble_received_target_power; + uint8_t msg1_fdm; + uint8_t msg1_frequency_start; + uint8_t zero_correlation_zone_config; + uint8_t subcarrier_spacing; + uint8_t restrictedset_config; + uint16_t root_sequence_index; + uint16_t rsrp_threshold_ssb; + uint16_t rsrp_threshold_sul; + uint16_t prach_freq_offset; + } fapi_nr_ul_config_prach_pdu; typedef struct { @@ -322,7 +252,7 @@ typedef struct { // pathlossReferenceRSs SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSs)) OF PUCCH-PathlossReferenceRS OPTIONAL, -- Need M int8_t twoPUCCH_PC_AdjustmentStates; - } fapi_nr_ul_config_uci_pdu; + } fapi_nr_ul_config_pucch_pdu; typedef enum {pusch_freq_hopping_disabled = 0 , pusch_freq_hopping_enabled = 1}pusch_freq_hopping_t; typedef struct{ @@ -352,39 +282,23 @@ typedef struct { uint8_t maxCodeBlockGroupsPerTransportBlock; uint8_t ptrs_dmrs_association_port; uint8_t beta_offset_ind; - } fapi_nr_ul_config_ulsch_pdu_rel15_t; + } fapi_nr_ul_config_pusch_pdu_rel15_t; typedef struct { uint16_t rnti; - fapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15; -} fapi_nr_ul_config_ulsch_pdu; + fapi_nr_ul_config_pusch_pdu_rel15_t ulsch_pdu_rel15; +} fapi_nr_ul_config_pusch_pdu; typedef struct { } fapi_nr_ul_config_srs_pdu; -// nFAPI enums -typedef enum { - FAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE = 0, - FAPI_NR_DL_CONFIG_BCH_PDU_TYPE, - FAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE, - FAPI_NR_DL_CONFIG_PCH_PDU_TYPE, -} fapi_nr_dl_config_pdu_type_e; - -// nFAPI enums -typedef enum { - FAPI_NR_UL_CONFIG_PRACH_PDU_TYPE = 0, - FAPI_NR_UL_CONFIG_ULSCH_PDU_TYPE, - FAPI_NR_UL_CONFIG_UCI_PDU_TYPE, - FAPI_NR_UL_CONFIG_SRS_PDU_TYPE, -} fapi_nr_ul_config_pdu_type_e; - typedef struct { uint8_t pdu_type; union { fapi_nr_ul_config_prach_pdu prach_config_pdu; - fapi_nr_ul_config_uci_pdu uci_config_pdu; - fapi_nr_ul_config_ulsch_pdu ulsch_config_pdu; + fapi_nr_ul_config_pucch_pdu pucch_config_pdu; + fapi_nr_ul_config_pusch_pdu ulsch_config_pdu; fapi_nr_ul_config_srs_pdu srs_config_pdu; }; } fapi_nr_ul_config_request_pdu_t; @@ -398,16 +312,15 @@ typedef struct { typedef struct { uint16_t rnti; - + uint16_t BWPSize; + uint16_t BWPStart; + uint8_t SubcarrierSpacing; fapi_nr_coreset_t coreset; - uint16_t N_RB_BWP; - uint32_t duration; - uint8_t number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16 - uint16_t monitoring_symbols_within_slot; - // DCI foramt-specific - uint8_t format_2_0_number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16 - uint8_t format_2_3_monitorying_periodicity; - uint8_t format_2_3_number_of_candidates; + uint8_t number_of_candidates; + uint16_t CCE[64]; + uint8_t L[64]; + uint8_t dci_length; + uint8_t dci_format; } fapi_nr_dl_config_dci_dl_pdu_rel15_t; typedef struct { @@ -420,12 +333,16 @@ typedef struct{ typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t; //typedef fapi_nr_dci_pdu_rel15_t fapi_nr_dl_config_dlsch_pdu_rel15_t; typedef struct { - uint8_t bandwidth_part_ind; + uint16_t BWPSize; + uint16_t BWPStart; + uint8_t SubcarrierSpacing; uint16_t number_rbs; uint16_t start_rb; uint8_t frame_offset; uint16_t number_symbols; uint16_t start_symbol; + uint16_t dlDmrsSymbPos; + uint8_t dmrsConfigType; uint8_t prb_bundling_size_ind; uint8_t rate_matching_ind; uint8_t zp_csi_rs_trigger; @@ -452,20 +369,6 @@ typedef struct { // to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t } fapi_nr_dl_config_dlsch_pdu_rel15_t; -typedef struct { - - uint8_t subcarrier_spacing_common; - uint8_t ssb_subcarrier_offset; - uint8_t dmrs_type_a_position; - uint8_t pdcch_config_sib1; - uint8_t cell_barred; - uint8_t intra_frequency_reselection; - - uint16_t system_frame_number; - uint8_t ssb_index; - uint8_t half_frame_bit; -} fapi_nr_dl_config_bch_pdu; - typedef struct { uint16_t rnti; fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config_rel15; @@ -474,7 +377,6 @@ typedef struct { typedef struct { uint8_t pdu_type; union { - fapi_nr_dl_config_bch_pdu bch_config_pdu; fapi_nr_dl_config_dci_pdu dci_config_pdu; fapi_nr_dl_config_dlsch_pdu dlsch_config_pdu; }; @@ -492,154 +394,6 @@ typedef struct { // -typedef struct { - uint8_t numerology_index_mu; - uint8_t duplex_mode; - uint8_t dl_cyclic_prefix_type; - uint8_t ul_cyclic_prefix_type; -} fapi_nr_subframe_config_t; - -typedef struct { - uint16_t dl_carrier_bandwidth; - uint16_t ul_carrier_bandwidth; - uint16_t dl_absolutefrequencypointA; - uint16_t ul_absolutefrequencypointA; - uint16_t dl_offsettocarrier; - uint16_t ul_offsettocarrier; - uint16_t dl_subcarrierspacing; - uint16_t ul_subcarrierspacing; - uint16_t dl_specificcarrier_k0; - uint16_t ul_specificcarrier_k0; - uint16_t NIA_subcarrierspacing; -} fapi_nr_rf_config_t; - -typedef struct { - uint16_t physical_cell_id; - uint8_t half_frame_index; - uint16_t ssb_subcarrier_offset; - uint16_t ssb_sib1_position_in_burst; // in sib1 - uint64_t ssb_scg_position_in_burst; // in servingcellconfigcommon - uint8_t ssb_periodicity; - uint16_t ss_pbch_block_power; - uint16_t n_ssb_crb; -} fapi_nr_sch_config_t; - -typedef struct { - uint16_t dl_bandwidth; - uint16_t ul_bandwidth; - uint16_t dl_offset; - uint16_t ul_offset; - uint8_t dl_subcarrierSpacing; - uint8_t ul_subcarrierSpacing; -} fapi_nr_initialBWP_config_t; - -#define FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS 16 -#define FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS 16 - -typedef struct { - uint16_t dmrs_TypeA_Position; - uint16_t num_PDSCHTimeDomainResourceAllocations; - uint16_t PDSCHTimeDomainResourceAllocation_k0[FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; - uint16_t PDSCHTimeDomainResourceAllocation_mappingType[FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; - uint16_t PDSCHTimeDomainResourceAllocation_startSymbolAndLength[FAPI_NR_PDSCH_CONFIG_MAXALLOCATIONS]; -} fapi_nr_pdsch_config_t; - -typedef struct { - uint16_t prach_RootSequenceIndex; ///// L1 parameter 'PRACHRootSequenceIndex' - uint16_t prach_msg1_SubcarrierSpacing; ///// L1 parameter 'prach-Msg1SubcarrierSpacing' - uint16_t restrictedSetConfig; - uint16_t msg3_transformPrecoding; ///// L1 parameter 'msg3-tp' - uint16_t ssb_perRACH_OccasionAndCB_PreamblesPerSSB; - uint16_t ra_ContentionResolutionTimer; - uint16_t rsrp_ThresholdSSB; - /////////////////--------------------NR RACH-ConfigGeneric--------------------///////////////// - uint16_t prach_ConfigurationIndex; ///// L1 parameter 'PRACHConfigurationIndex' - uint16_t prach_msg1_FDM; ///// L1 parameter 'prach-FDM' - uint16_t prach_msg1_FrequencyStart; ///// L1 parameter 'prach-frequency-start' - uint16_t zeroCorrelationZoneConfig; - uint16_t preambleReceivedTargetPower; - uint16_t preambleTransMax; - uint16_t powerRampingStep; - uint16_t ra_ResponseWindow; -} fapi_nr_rach_config_t; - -typedef struct { - uint16_t groupHoppingEnabledTransformPrecoding; ///// L1 parameter 'Group-hopping-enabled-Transform-precoding' - uint16_t msg3_DeltaPreamble; ///// L1 parameter 'Delta-preamble-msg3' - uint16_t p0_NominalWithGrant; ///// L1 parameter 'p0-nominal-pusch-withgrant' - uint16_t dmrs_TypeA_Position; - uint16_t num_PUSCHTimeDomainResourceAllocations; - uint16_t PUSCHTimeDomainResourceAllocation_k2[FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'K2' - uint16_t PUSCHTimeDomainResourceAllocation_mappingType[FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; ///// L1 parameter 'Mapping-type' - uint16_t PUSCHTimeDomainResourceAllocation_startSymbolAndLength[FAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS]; -} fapi_nr_pusch_config_t; - -typedef struct { - uint8_t pucch_resource_common; - uint16_t pucch_GroupHopping; ///// L1 parameter 'PUCCH-GroupHopping' - uint8_t hopping_id; - uint16_t p0_nominal; ///// L1 parameter 'p0-nominal-pucch' -} fapi_nr_pucch_config_t; - -typedef struct { - uint8_t controlResourceSetZero; - uint8_t searchSpaceZero; - - // fapi_nr_SearchSpace_t sib1searchSpace; - // fapi_nr_SearchSpace_t sibssearchSpace; - // fapi_nr_SearchSpace_t ra_SearchSpace; -} fapi_nr_pdcch_config_t; - -typedef struct { -//NR TDD-UL-DL-ConfigCommon ///// L1 parameter 'UL-DL-configuration-common' - uint16_t referenceSubcarrierSpacing; ///// L1 parameter 'reference-SCS' - uint16_t dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity' - uint16_t nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots' - uint16_t nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common' - uint16_t nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots' - uint16_t nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common' - uint16_t Pattern2Present; - uint16_t Pattern2_dl_ul_periodicity; ///// L1 parameter 'DL-UL-transmission-periodicity' - uint16_t Pattern2_nrofDownlinkSlots; ///// L1 parameter 'number-of-DL-slots' - uint16_t Pattern2_nrofDownlinkSymbols; ///// L1 parameter 'number-of-DL-symbols-common' - uint16_t Pattern2_nrofUplinkSlots; ///// L1 parameter 'number-of-UL-slots' - uint16_t Pattern2_nrofUplinkSymbols; ///// L1 parameter 'number-of-UL-symbols-common' -} fapi_nr_tdd_ul_dl_config_t; - -#define FAPI_MAX_NUM_RF_BANDS 16 -typedef struct { - uint16_t number_rf_bands; - uint16_t rf_band[FAPI_MAX_NUM_RF_BANDS]; -} fapi_rf_bands_t; - -typedef struct -{ - fapi_rf_bands_t rf_bands; - - uint32_t nrarfcn; - - // nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands; - // nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands; - // nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands; - // nfapi_uint8_tlv_t nmm_uplink_rssi_supported; - -} fapi_nr_fapi_t; - -typedef struct { - fapi_nr_fapi_t fapi_config; - fapi_nr_subframe_config_t subframe_config; - fapi_nr_rf_config_t rf_config; - fapi_nr_sch_config_t sch_config; - fapi_nr_initialBWP_config_t initialBWP_config; - fapi_nr_pdsch_config_t pdsch_config; - fapi_nr_rach_config_t rach_config; - fapi_nr_pusch_config_t pusch_config; - fapi_nr_pucch_config_t pucch_config; - fapi_nr_pdcch_config_t pdcch_config; - fapi_nr_tdd_ul_dl_config_t tdd_ul_dl_config; - // fapi_nr_ratematchpattern_t ratematchpattern; - // fapi_nr_ratematchpattern_lte_crs_t ratematchpattern_lte_crs; -} fapi_nr_config_request_t; typedef struct { fapi_nr_coreset_t coreset; @@ -723,6 +477,19 @@ typedef struct { uint8_t p0_nominal; } fapi_nr_pucch_config_common_t; +typedef struct { + + uint8_t subcarrier_spacing_common; + uint8_t ssb_subcarrier_offset; + uint8_t dmrs_type_a_position; + uint8_t pdcch_config_sib1; + uint8_t cell_barred; + uint8_t intra_frequency_reselection; + + uint16_t system_frame_number; + uint8_t ssb_index; + uint8_t half_frame_bit; +} fapi_nr_pbch_config_t; typedef struct { @@ -859,6 +626,7 @@ typedef struct { fapi_nr_pdsch_config_dedicated_t pdsch_config_dedicated; fapi_nr_sps_config_t sps_config; fapi_nr_radio_link_monitoring_config_t radio_link_monitoring_config; + } fapi_nr_dl_bwp_dedicated_config_t; typedef struct { @@ -1072,4 +840,18 @@ typedef struct { #define FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_DEDICATED 0x08 #define FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_DEDICATED 0x10 +typedef struct { + uint32_t config_mask; + + fapi_nr_pbch_config_t pbch_config; // MIB + + fapi_nr_dl_bwp_common_config_t dl_bwp_common; + fapi_nr_dl_bwp_dedicated_config_t dl_bwp_dedicated; + + fapi_nr_ul_bwp_common_config_t ul_bwp_common; + fapi_nr_ul_bwp_dedicated_config_t ul_bwp_dedicated; + +} fapi_nr_config_request_t; + #endif + diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index 525baef291..5f12fc55b9 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -11,48 +11,16 @@ #include "nfapi_interface.h" - #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 #define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 #define NFAPI_NR_MAX_NB_CORESETS 12 #define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 -// Extension to the generic structures for single tlv values -typedef struct { - nfapi_tl_t tl; - int32_t value; -} nfapi_int32_tlv_t; -typedef struct { - nfapi_tl_t tl; - uint32_t value; -} nfapi_uint32_tlv_t; - -/*typedef struct { - nfapi_tl_t tl; - int64_t value; -} nfapi_int64_tlv_t;*/ - -typedef struct { - nfapi_tl_t tl; - uint64_t value; -} nfapi_uint64_tlv_t; // nFAPI enums -typedef enum { - NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE = 0, - NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE, - NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE, - NFAPI_NR_DL_CONFIG_PCH_PDU_TYPE, -} nfapi_nr_dl_config_pdu_type_e; -// nFAPI enums -typedef enum { - NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE = 0, - NFAPI_NR_UL_CONFIG_ULSCH_PDU_TYPE, - NFAPI_NR_UL_CONFIG_UCI_PDU_TYPE, - NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE, -} nfapi_nr_ul_config_pdu_type_e; + //These TLVs are used exclusively by nFAPI typedef struct @@ -111,37 +79,6 @@ typedef struct // P5 Message Structures -typedef struct{ - nfapi_tl_t tl; - uint16_t corset_ID; ///// L1 parameter 'CORESET-ID' - uint16_t freq_dom; ///// L1 parameter 'CORESET-freq-dom' - uint16_t duration; ///// L1 parameter 'CORESET-time-duration' - uint16_t reg_type; ///// L1 parameter 'CORESET-CCE-REG-mapping-type' - uint16_t reg_bundlesize; ///// L1 parameter 'CORESET-REG-bundle-size' - uint16_t interleaversize; ///// L1 parameter 'CORESET-interleaver-size' - uint16_t shiftindex; ///// L1 parameter 'CORESET-shift-index' - uint16_t precodergranularity; ///// L1 parameter 'CORESET-precoder-granuality' - uint16_t tci_stateId; ///// L1 parameter 'TCI-StatesPDCCH' - uint16_t tci_present; ///// L1 parameter 'TCI-PresentInDCI' - uint16_t dmrs_scramblingID; ///// L1 parameter 'PDCCH-DMRS-Scrambling-ID' -} nfapi_nr_ControlResourcesSet_t; - -typedef struct{ - nfapi_tl_t tl; - nfapi_nr_ControlResourcesSet_t coreset; - uint16_t monitoringSlotPeriodicityAndOffset; ///// L1 parameters 'Montoring-periodicity-PDCCH-slot' - uint16_t monitoringSymbolsWithinSlot; ///// L1 parameter 'Montoring-symbols-PDCCH-within-slot' - uint16_t nrofCand_aggLevel1; ///// L1 parameter 'Aggregation-level-1' - uint16_t nrofCand_aggLevel2; ///// L1 parameter 'Aggregation-level-2' - uint16_t nrofCand_aggLevel4; ///// L1 parameter 'Aggregation-level-4' - uint16_t nrofCand_aggLevel8; ///// L1 parameter 'Aggregation-level-8' - uint16_t nrofCand_aggLevel16; ///// L1 parameter 'Aggregation-level-16' - uint16_t sfi_agg_fmt2_0; ///// L1 parameters 'SFI-Num-PDCCH-cand' and 'SFI-Aggregation-Level' - uint16_t monitoringperiodicity_fmt2_3; ///// L1 parameter 'SRS-monitoring-periodicity' - uint16_t nrof_candidates_fmt_2_3; ///// L1 parameter 'SRS-Num-PDCCH-cand' -} nfapi_nr_SearchSpace_t; - - typedef struct { nfapi_uint16_tlv_t numerology_index_mu; nfapi_uint16_tlv_t duplex_mode; @@ -457,13 +394,9 @@ typedef enum { NFAPI_NR_MCS_TABLE_QAM256 } nfapi_nr_pdsch_mcs_table_e; -typedef enum { - NFAPI_NR_DMRS_TYPE1=0, - NFAPI_NR_DMRS_TYPE2 -} nfapi_nr_dmrs_type_e; - // P7 Sub Structures +/* typedef struct { nfapi_tl_t tl; @@ -526,9 +459,12 @@ uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 uint16_t padding; } nfapi_nr_dl_config_dci_dl_pdu_rel15_t; - +*/ //#define NFAPI_NR_DL_CONFIG_REQUEST_DCI_DL_PDU_REL15_TAG 0x???? + + +/* typedef struct{ nfapi_tl_t tl; uint8_t coreset_id; @@ -563,11 +499,13 @@ typedef struct{ uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS]; } nfapi_nr_search_space_t; + typedef struct { nfapi_tl_t tl; uint16_t rnti; uint8_t rnti_type; uint8_t dci_format; + uint16_t cce_index; /// Number of CRB in BWP that this DCI configures uint16_t n_RB_BWP; uint8_t config_type; @@ -592,108 +530,7 @@ typedef struct { nfapi_bf_vector_t bf_vector; } nfapi_nr_dl_config_pdcch_parameters_rel15_t; -typedef struct { - nfapi_tl_t tl; - uint16_t length; - int16_t pdu_index; - uint16_t transmission_power; -} nfapi_nr_dl_config_bch_pdu_rel15_t; -#define NFAPI_NR_DL_CONFIG_REQUEST_BCH_PDU_REL15_TAG 0x5025 - -typedef struct { - nfapi_nr_dl_config_bch_pdu_rel15_t bch_pdu_rel15; -} nfapi_nr_dl_config_bch_pdu; - -typedef struct { - nfapi_tl_t tl; - uint16_t length; - uint8_t pdu_index; - uint16_t rnti; - uint16_t nb_mod_symbols; - uint8_t time_allocation_type; - uint8_t freq_allocation_type; - uint16_t start_prb; - uint16_t n_prb; - uint8_t start_symbol; - uint8_t nb_symbols; - uint8_t mcs_idx; - uint8_t ndi; - uint8_t nb_codewords; - uint8_t nb_layers; - uint16_t coding_rate; - uint8_t modulation; - uint8_t modulation_order; - uint16_t transport_block_size; - uint8_t dmrs_Type; - uint8_t dmrs_TypeA_Position; - uint8_t dmrs_maxLength; - uint8_t dmrs_AdditionalPosition; - uint8_t time_alloc_list_flag; - uint8_t time_alloc_list; - uint8_t mapping_type; - uint8_t rbg_list; - uint8_t virtual_resource_block_assignment_flag; - uint32_t resource_block_coding; - uint8_t redundancy_version; - uint8_t transport_blocks; - uint8_t transmission_scheme; - uint8_t number_of_subbands; - uint8_t codebook_index[NFAPI_MAX_NUM_SUBBANDS]; - uint8_t ue_category_capacity; - uint8_t x_overhead; - uint8_t pa; - uint8_t delta_power_offset_index; - uint8_t ngap; - uint8_t transmission_mode; - uint8_t num_bf_prb_per_subband; - uint8_t num_bf_vector; - nfapi_bf_vector_t bf_vector[NFAPI_MAX_BF_VECTORS]; -}nfapi_nr_dl_config_dlsch_pdu_rel15_t; -#define NFAPI_NR_DL_CONFIG_REQUEST_DLSCH_PDU_REL15_TAG - -typedef struct { - nfapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_pdu_rel15; -} nfapi_nr_dl_config_dlsch_pdu; - -typedef struct { - nfapi_tl_t tl; - nfapi_nr_search_space_t pagingSearchSpace; - nfapi_nr_coreset_t pagingControlResourceSets; -}nfapi_nr_dl_config_pch_pdu_rel15_t; - -typedef struct { - nfapi_nr_dl_config_dci_dl_pdu_rel15_t dci_dl_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params_rel15; -} nfapi_nr_dl_config_dci_dl_pdu; - - -typedef struct { - uint8_t pdu_type; - uint8_t pdu_size; - - union { - nfapi_nr_dl_config_dci_dl_pdu dci_dl_pdu; - nfapi_nr_dl_config_bch_pdu_rel15_t bch_pdu_rel15; - nfapi_nr_dl_config_dlsch_pdu dlsch_pdu; - nfapi_nr_dl_config_pch_pdu_rel15_t pch_pdu_rel15; - }; -} nfapi_nr_dl_config_request_pdu_t; - - -typedef struct { - nfapi_tl_t tl; - uint8_t number_dci; - uint8_t number_pdu; - uint8_t number_pdsch_rnti; - nfapi_nr_dl_config_request_pdu_t *dl_config_pdu_list; -} nfapi_nr_dl_config_request_body_t; - -typedef struct { - nfapi_p7_message_header_t header; - uint16_t sfn_sf; - nfapi_nr_dl_config_request_body_t dl_config_request_body; - nfapi_vendor_extension_tlv_t vendor_extension; -} nfapi_nr_dl_config_request_t; +*/ typedef enum {nr_pusch_freq_hopping_disabled = 0 , @@ -716,6 +553,7 @@ typedef struct { nr_pusch_freq_hopping_t pusch_freq_hopping; uint8_t mcs; uint8_t Qm; + uint16_t R; uint8_t ndi; uint8_t rv; int8_t accumulated_delta_PUSCH; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h new file mode 100644 index 0000000000..ee1550a5bb --- /dev/null +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -0,0 +1,1646 @@ +/* + nfapi_nr_interface.h + ------------------- + AUTHOR : Chenyu Zhang, Florian Kaltenberger + COMPANY : BUPT, EURECOM + EMAIL : octopus@bupt.edu.cn, florian.kaltenberger@eurecom.fr +*/ + +#ifndef _NFAPI_NR_INTERFACE_SCF_H_ +#define _NFAPI_NR_INTERFACE_SCF_H_ + +#include "stddef.h" +#include "nfapi_interface.h" + +#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5 +#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64 +#define NFAPI_NR_MAX_NB_CORESETS 12 +#define NFAPI_NR_MAX_NB_SEARCH_SPACES 40 + +#define NFAPI_MAX_NUM_UL_UE_PER_GROUP 6 +#define NFAPI_MAX_NUM_UL_PDU 8 +#define NFAPI_MAX_NUM_GROUPS 8 +#define NFAPI_MAX_NUM_CB 8 + +// Extension to the generic structures for single tlv values +typedef struct { + nfapi_tl_t tl; + int32_t value; +} nfapi_int32_tlv_t; + +typedef struct { + nfapi_tl_t tl; + uint32_t value; +} nfapi_uint32_tlv_t; + +typedef struct { + nfapi_tl_t tl; + int64_t value; +} nfapi_int64_tlv_t; + +typedef struct { + nfapi_tl_t tl; + uint64_t value; +} nfapi_uint64_tlv_t; + +typedef enum { + NFAPI_NR_DMRS_TYPE1=0, + NFAPI_NR_DMRS_TYPE2 +} nfapi_nr_dmrs_type_e; + + +typedef struct { + /// Value: 0 -> 1, 0: Payload is carried directly in the value field, 1: Pointer to payload is in the value field + uint16_t tag; + /// Length of the actual payload in bytes, without the padding bytes Value: 0 → 65535 + uint16_t length; + union { + uint32_t *ptr; + uint32_t direct[16384]; + } value; +} nfapi_nr_tx_data_request_tlv_t; + + +// 2019.8 +// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.2 + +//PHY API message types + +typedef enum { + NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST= 0x00, + NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE= 0x01, + NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST= 0x02, + NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE=0X03, + NFAPI_NR_PHY_MSG_TYPE_START_REQUEST= 0X04, + NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST= 0X05, + NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06, + NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07, + //RESERVED 0X08 ~ 0X7F + NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST= 0X80, + NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST= 0X81, + NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION=0X82, + NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST= 0X83, + NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X54, + NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION=0X85, + NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86, + NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87, + NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88, + NFAPI_NR_PHY_MSG_TYPE_PACH_INDICATION= 0X89 + //RESERVED 0X8a ~ 0xff +} nfapi_nr_phy_msg_type_e; + +// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.3 + +//3.3.1 PARAM + +//same with nfapi_param_request_t +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_param_request_t; + +typedef enum { + NFAPI_NR_PARAM_MSG_OK = 0, + NFAPI_NR_PARAM_MSG_INVALID_STATE + +} nfapi_nr_param_errors_e; + +/*typedef struct { + nfapi_nr_param_errors_e error_code; + //Number of TLVs contained in the message body. + uint8_t number_of_tlvs; + nfapi_nr_param_tlv_t TLV; +} nfapi_nr_param_response_t;*/ + + +//PARAM and CONFIG TLVs are used in the PARAM and CONFIG message exchanges, respectively + + +//nfapi_nr_param_tlv_format_t cell param ~ measurement_param: + +//table 3-9 + +#define NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG 0x0001 +#define NFAPI_NR_PARAM_TLV_PHY_STATE_TAG 0x0002 +#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG 0x0003 +#define NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG 0x0004 +#define NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG 0x0005 +#define NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG 0x0006 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG 0x0007 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG 0x0008 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG 0x0009 +#define NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG 0x000A +#define NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG 0x000B +#define NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG 0x000C +#define NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG 0x000D +#define NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG 0x000E +#define NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG 0x000F +#define NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG 0x0010 +#define NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG 0x0011 +#define NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG 0x0012 +#define NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG 0x0013 +#define NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG 0x0014 +#define NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG 0x0015 +#define NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG 0x0016 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG 0x0017 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG 0x0018 +#define NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG 0x0019 +#define NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG 0x001A +#define NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG 0x001B +#define NFAPI_NR_PARAM_TLV_SUPPORTED_MAX_MODULATION_ORDER_DL_TAG 0x001C +#define NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG 0x001D +#define NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG 0x001E +#define NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG 0x001F +#define NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG 0x0020 +#define NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG 0x0021 +#define NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG 0x0022 +#define NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG 0x0023 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG 0x0024 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG 0x0025 +#define NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG 0x0026 +#define NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG 0x0027 +#define NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG 0x0028 +#define NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG 0x0029 +#define NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG 0x002A +#define NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG 0x002B +#define NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG 0x002C +#define NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG 0x002D +#define NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG 0x002E +#define NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG 0x002F +#define NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG 0x0030 +#define NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG 0x0031 +#define NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG 0x0032 +#define NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG 0x0033 +#define NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG 0x0034 +#define NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG 0x0035 +#define NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG 0x0036 + +typedef struct +{ + nfapi_uint16_tlv_t release_capability; //TAG 0x0001 + nfapi_uint16_tlv_t phy_state; + nfapi_uint8_tlv_t skip_blank_dl_config; + nfapi_uint8_tlv_t skip_blank_ul_config; + nfapi_uint16_tlv_t num_config_tlvs_to_report; + nfapi_uint8_tlv_t* config_tlvs_to_report_list; +} nfapi_nr_cell_param_t; + +//table 3-10 Carrier parameters +typedef struct +{ + nfapi_uint8_tlv_t cyclic_prefix;//TAG 0x0006 + nfapi_uint16_tlv_t supported_subcarrier_spacings_dl; + nfapi_uint16_tlv_t supported_bandwidth_dl; + nfapi_uint8_tlv_t supported_subcarrier_spacings_ul; + nfapi_uint16_tlv_t supported_bandwidth_ul; + +} nfapi_nr_carrier_param_t; + +//table 3-11 PDCCH parameters +typedef struct +{ + nfapi_uint8_tlv_t cce_mapping_type; + nfapi_uint8_tlv_t coreset_outside_first_3_of_ofdm_syms_of_slot; + nfapi_uint8_tlv_t coreset_precoder_granularity_coreset; + nfapi_uint8_tlv_t pdcch_mu_mimo; + nfapi_uint8_tlv_t pdcch_precoder_cycling; + nfapi_uint8_tlv_t max_pdcch_per_slot;//TAG 0x0010 + +} nfapi_nr_pdcch_param_t; + +//table 3-12 PUCCH parameters +typedef struct +{ + nfapi_uint8_tlv_t pucch_formats; + nfapi_uint8_tlv_t max_pucchs_per_slot; + +} nfapi_nr_pucch_param_t; + +//table 3-13 PDSCH parameters +typedef struct +{ + nfapi_uint8_tlv_t pdsch_mapping_type; + nfapi_uint8_tlv_t pdsch_allocation_types; + nfapi_uint8_tlv_t pdsch_vrb_to_prb_mapping; + nfapi_uint8_tlv_t pdsch_cbg; + nfapi_uint8_tlv_t pdsch_dmrs_config_types; + nfapi_uint8_tlv_t pdsch_dmrs_max_length; + nfapi_uint8_tlv_t pdsch_dmrs_additional_pos; + nfapi_uint8_tlv_t max_pdsch_tbs_per_slot; + nfapi_uint8_tlv_t max_number_mimo_layers_pdsch; + nfapi_uint8_tlv_t supported_max_modulation_order_dl; + nfapi_uint8_tlv_t max_mu_mimo_users_dl; + nfapi_uint8_tlv_t pdsch_data_in_dmrs_symbols; + nfapi_uint8_tlv_t premption_support;//TAG 0x001F + nfapi_uint8_tlv_t pdsch_non_slot_support; + +} nfapi_nr_pdsch_param_t; + +//table 3-14 +typedef struct +{ + nfapi_uint8_tlv_t uci_mux_ulsch_in_pusch; + nfapi_uint8_tlv_t uci_only_pusch; + nfapi_uint8_tlv_t pusch_frequency_hopping; + nfapi_uint8_tlv_t pusch_dmrs_config_types; + nfapi_uint8_tlv_t pusch_dmrs_max_len; + nfapi_uint8_tlv_t pusch_dmrs_additional_pos; + nfapi_uint8_tlv_t pusch_cbg; + nfapi_uint8_tlv_t pusch_mapping_type; + nfapi_uint8_tlv_t pusch_allocation_types; + nfapi_uint8_tlv_t pusch_vrb_to_prb_mapping; + nfapi_uint8_tlv_t pusch_max_ptrs_ports; + nfapi_uint8_tlv_t max_pduschs_tbs_per_slot; + nfapi_uint8_tlv_t max_number_mimo_layers_non_cb_pusch; + nfapi_uint8_tlv_t supported_modulation_order_ul; + nfapi_uint8_tlv_t max_mu_mimo_users_ul; + nfapi_uint8_tlv_t dfts_ofdm_support; + nfapi_uint8_tlv_t pusch_aggregation_factor;//TAG 0x0031 + +} nfapi_nr_pusch_param_t; + +//table 3-15 +typedef struct +{ + nfapi_uint8_tlv_t prach_long_formats; + nfapi_uint8_tlv_t prach_short_formats; + nfapi_uint8_tlv_t prach_restricted_sets; + nfapi_uint8_tlv_t max_prach_fd_occasions_in_a_slot; +} nfapi_nr_prach_param_t; + +//table 3-16 +typedef struct +{ + nfapi_uint8_tlv_t rssi_measurement_support; +} nfapi_nr_measurement_param_t; + +//-------------------------------------------// +//3.3.2 CONFIG + + +typedef enum { + NFAPI_NR_CONFIG_MSG_OK = 0, + NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state. +} nfapi_nr_config_errors_e; + +/*typedef struct { + nfapi_nr_config_errors_e error_code; + uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle; + uint8_t unmber_of_missing_tlvs; + //? ↓ + nfapi_nr_config_tlv_t* tlv_invalid_list; + nfapi_nr_config_tlv_t* tlv_invalid_idle_list; + nfapi_nr_config_tlv_t* tlv_invalid_running_list; + nfapi_nr_config_tlv_t* tlv_missing_list; + +} nfapi_nr_config_response_t;*/ + +//nfapi_nr_config_tlv_format_t carrier config ~ precoding config: + +#define NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG 0x1001 +#define NFAPI_NR_CONFIG_DL_FREQUENCY_TAG 0x1002 +#define NFAPI_NR_CONFIG_DL_K0_TAG 0x1003 +#define NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG 0x1004 +#define NFAPI_NR_CONFIG_NUM_TX_ANT_TAG 0x1005 +#define NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG 0x1006 +#define NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG 0x1007 +#define NFAPI_NR_CONFIG_UL_K0_TAG 0x1008 +#define NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG 0x1009 +#define NFAPI_NR_CONFIG_NUM_RX_ANT_TAG 0x100A +#define NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG 0x100B + +#define NFAPI_NR_CONFIG_PHY_CELL_ID_TAG 0x100C +#define NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG 0x100D + +#define NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG 0x100E +#define NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG 0x100F +#define NFAPI_NR_CONFIG_SCS_COMMON_TAG 0x1010 + +#define NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG 0x1011 +#define NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG 0x1012 +#define NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG 0x1013 +#define NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG 0x1014 +#define NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG 0x1015 +#define NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG 0x1016 +#define NFAPI_NR_CONFIG_K1_TAG 0x1017 +#define NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG 0x1018 +#define NFAPI_NR_CONFIG_NUM_UNUSED_ROOT_SEQUENCES_TAG 0x1019 +#define NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG 0x101A +#define NFAPI_NR_CONFIG_SSB_PER_RACH_TAG 0x101B +#define NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG 0x101C + +#define NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG 0x101D +#define NFAPI_NR_CONFIG_BETA_PSS_TAG 0x101E +#define NFAPI_NR_CONFIG_SSB_PERIOD_TAG 0x101F +#define NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG 0x1020 +#define NFAPI_NR_CONFIG_MIB_TAG 0x1021 +#define NFAPI_NR_CONFIG_SSB_MASK_TAG 0x1022 +#define NFAPI_NR_CONFIG_BEAM_ID_TAG 0x1023 +#define NFAPI_NR_CONFIG_SS_PBCH_MULTIPLE_CARRIERS_IN_A_BAND_TAG 0x1024 +#define NFAPI_NR_CONFIG_MULTIPLE_CELLS_SS_PBCH_IN_A_CARRIER_TAG 0x1025 +#define NFAPI_NR_CONFIG_TDD_PERIOD_TAG 0x1026 +#define NFAPI_NR_CONFIG_SLOT_CONFIG_TAG 0x1027 + +#define NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG 0x1028 + +//table 3-21 +typedef struct +{ + nfapi_uint16_tlv_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400 + nfapi_uint32_tlv_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 + nfapi_uint16_tlv_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699 + nfapi_uint16_tlv_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used + nfapi_uint16_tlv_t num_tx_ant;//Number of Tx antennas + nfapi_uint16_tlv_t uplink_bandwidth;//Carrier bandwidth for UL in MHz. [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400 + nfapi_uint32_tlv_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000 + nfapi_uint16_tlv_t ul_k0[5];//𝑘0 𝜇 for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699 + nfapi_uint16_tlv_t ul_grid_size[5];//Grid size 𝑁𝑔𝑟𝑖𝑑 𝑠𝑖𝑧𝑒,𝜇 for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used + nfapi_uint16_tlv_t num_rx_ant;// + nfapi_uint8_tlv_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true + +} nfapi_nr_carrier_config_t; + +//table 3-22 +typedef struct +{ + nfapi_uint8_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007 + nfapi_uint8_tlv_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD + +} nfapi_nr_cell_config_t; + +//table 3-23 +typedef struct +{ + nfapi_uint32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm) + nfapi_uint8_tlv_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload + nfapi_uint8_tlv_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3 + +} nfapi_nr_ssb_config_t; + +//table 3-24 +/*typedef struct { + uint8_t unused_root_sequences;//Unused root sequence or sequences per FD occasion. Required for noise estimation. +} nfapi_nr_num_unused_root_sequences_t;*/ + +typedef struct +{ + uint8_t num_prach_fd_occasions; + nfapi_uint16_tlv_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837 + nfapi_uint8_tlv_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles + nfapi_uint16_tlv_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272 + nfapi_uint8_tlv_t prach_zero_corr_conf;//PRACH Zero CorrelationZone Config which is used to dervive 𝑁𝑐𝑠 [38.211, sec 6.3.3.1] Value: from 0 to 15 + nfapi_uint8_tlv_t num_unused_root_sequences;//Number of unused sequences available for noise estimation per FD occasion. At least one unused root sequence is required per FD occasion. + nfapi_uint8_tlv_t* unused_root_sequences_list;//Unused root sequence or sequences per FD occasion. Required for noise estimation. + +} nfapi_nr_num_prach_fd_occasions_t; + +typedef struct +{ + nfapi_uint8_tlv_t prach_sequence_length;//RACH sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence + nfapi_uint8_tlv_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4 + nfapi_uint8_tlv_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B + nfapi_uint8_tlv_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8 + nfapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list; + nfapi_uint8_tlv_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16 + nfapi_uint8_tlv_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + +} nfapi_nr_prach_config_t; + +//table 3-25 +typedef struct +{ + nfapi_uint32_tlv_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted + +} nfapi_nr_ssb_mask_size_2_t; + +typedef struct +{ + nfapi_uint8_tlv_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63 + +} nfapi_nr_ssb_mask_size_64_t; + +typedef struct +{ + nfapi_uint16_tlv_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199 + nfapi_uint8_tlv_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB + nfapi_uint8_tlv_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 + nfapi_uint8_tlv_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 + nfapi_uint32_tlv_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1] + nfapi_nr_ssb_mask_size_2_t ssb_mask_list[2]; + nfapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64 + nfapi_uint8_tlv_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + nfapi_uint8_tlv_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled + +} nfapi_nr_ssb_table_t; + +//table 3-26 + +//? +typedef struct +{ + nfapi_uint8_tlv_t slot_config;//For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot + +} nfapi_nr_max_num_of_symbol_per_slot_t; + +typedef struct +{ + nfapi_nr_max_num_of_symbol_per_slot_t* max_num_of_symbol_per_slot_list; + +} nfapi_nr_max_tdd_periodicity_t; + +typedef struct +{ + nfapi_uint8_tlv_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4 + nfapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list; + +} nfapi_nr_tdd_table_t; + +//table 3-27 +typedef struct +{ + nfapi_uint8_tlv_t rssi_measurement;//RSSI measurement unit. See Table 3-16 for RSSI definition. Value: 0: Do not report RSSI 1: dBm 2: dBFS + +} nfapi_nr_measurement_config_t; + + +typedef struct { + uint8_t num_tlv; + nfapi_nr_carrier_config_t carrier_config; + nfapi_nr_cell_config_t cell_config; + nfapi_nr_ssb_config_t ssb_config; + nfapi_nr_prach_config_t prach_config; + nfapi_nr_ssb_table_t ssb_table; + nfapi_nr_tdd_table_t tdd_table; + nfapi_nr_measurement_config_t measurement_config; +} nfapi_nr_config_request_scf_t; + + +//------------------------------// +//3.3.3 START + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_start_request_t; + +typedef enum { + NFAPI_NR_START_MSG_INVALID_STATE +} nfapi_nr_start_errors_e; + +//3.3.4 STOP + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_stop_request_t; + +typedef struct { + nfapi_p4_p5_message_header_t header; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_stop_indication_t; + +typedef enum { + NFAPI_NR_STOP_MSG_INVALID_STATE +} nfapi_nr_stop_errors_e; + +//3.3.5 PHY Notifications +typedef enum { + NFAPI_NR_PHY_API_MSG_OK =0x0, + NFAPI_NR_PHY_API_MSG_INVALID_STATE =0x1, + NFAPI_NR_PHY_API_MSG_INVALID_CONFIG =0x2, + NFAPI_NR_PHY_API_SFN_OUT_OF_SYNC =0X3, + NFAPI_NR_PHY_API_MSG_SLOR_ERR =0X4, + NFAPI_NR_PHY_API_MSG_BCH_MISSING =0X5, + NFAPI_NR_PHY_API_MSG_INVALID_SFN =0X6, + NFAPI_NR_PHY_API_MSG_UL_DCI_ERR =0X7, + NFAPI_NR_PHY_API_MSG_TX_ERR =0X8 +} nfapi_nr_phy_notifications_errors_e; + +typedef struct { + uint16_t sfn; //0~1023 + uint16_t slot;//0~319 + nfapi_nr_phy_msg_type_e msg_id;//Indicate which message received by the PHY has an error. Values taken from Table 3-4. + nfapi_nr_phy_notifications_errors_e error_code; +} nfapi_nr_phy_notifications_error_indicate_t; + +//-----------------------// +//3.3.6 Storing Precoding and Beamforming Tables + +//table 3-32 +//? +typedef struct { + uint16_t beam_idx; //0~65535 +} nfapi_nr_dig_beam_t; + +typedef struct { + uint16_t dig_beam_weight_Re; + uint16_t dig_beam_weight_Im; +} nfapi_nr_txru_t; + +typedef struct { + uint16_t num_dig_beams; //0~65535 + uint16_t num_txrus; //0~65535 + nfapi_nr_dig_beam_t* dig_beam_list; + nfapi_nr_txru_t* txru_list; +} nfapi_nr_dbt_pdu_t; + + +//table 3-33 +//? +typedef struct { + uint16_t num_ant_ports; + int16_t precoder_weight_Re; + int16_t precoder_weight_Im; +} nfapi_nr_num_ant_ports_t; + +typedef struct { + uint16_t numLayers; //0~65535 + nfapi_nr_num_ant_ports_t* num_ant_ports_list; +} nfapi_nr_num_layers_t; + +typedef struct { + uint16_t pm_idx; //0~65535 + nfapi_nr_num_layers_t* num_layers_list; //0~65535 + //nfapi_nr_num_ant_ports_t* num_ant_ports_list; +} nfapi_nr_pm_pdu_t; + + +// Section 3.4 + +// Section 3.4.1 slot indication +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_0 1000 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_1 50 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_2 250 //us +#define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_3 125 //us + +typedef struct { + uint16_t sfn; //0->1023 + uint16_t slot;//0->319 + +} nfapi_nr_slot_indication_t; + +// 3.4.2 + +//for pdcch_pdu: + +typedef struct +{ + uint16_t beam_idx;//Index of the digital beam weight vector pre-stored at cell configuration. The vector maps this input port to output TXRUs. Value: 0->65535 + +}nfapi_nr_dig_bf_interface_t; + +typedef struct +{ + uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535. + nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + +}nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t; + +/* +//table 3-43 +typedef struct +{ + uint16_t num_prgs;//Number of PRGs spanning this allocation. Value : 1->275 + uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 + //watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface + uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 + nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t* prgs_list;// + +}nfapi_nr_tx_precoding_and_beamforming_t; +*/ + +typedef struct { + /// Number of PRGs spanning this allocation. Value : 1->275 + uint16_t numPRGs; + /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 + uint16_t prgSize; + /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 + uint8_t digBFInterfaces; + uint16_t PMIdx[275]; + uint16_t *beamIdx[275]; +} nfapi_nr_tx_precoding_and_beamforming_t; + +//table 3-37 + +#define DCI_PAYLOAD_BTYE_LEN 12 //? TS38.212 sec 7.3.1 + +typedef struct +{ + uint16_t rnti;// + uint16_t scrambling_id;// + uint16_t scrambling_rnti;/* */ + uint8_t cce_index;// + uint8_t aggregation_level;// + nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list; + //tx power info + uint8_t beta_pdcch_1_0;/*PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of +SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */ + uint8_t power_control_offset_ss;//PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + uint16_t payload_size_bits;//The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0-> DCI_PAYLOAD_BTYE_LEN*8 + uint8_t payload[DCI_PAYLOAD_BTYE_LEN];//DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB + +} nfapi_nr_dl_dci_pdu_t; + +typedef struct { + /// Number of PRGs spanning this allocation. Value : 1->275 + uint16_t numPRGs; + /// Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275 + uint16_t prgSize; + /// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255 + uint8_t digBFInterfaces; + uint16_t PMIdx[275]; + uint16_t *beamIdx[275]; +} nr_beamforming_t; + +#define MAX_DCI_CORESET 8 +#define DCI_PAYLOAD_BYTE_LEN 8 + +typedef struct { + ///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275 + uint16_t BWPSize; + ///bandwidth part start RB index from reference CRB, [TS38.213 sec 12], Value: 0->274 + uint16_t BWPStart; + ///subcarrierSpacing [TS38.211 sec 4.2], Value:0->4 + uint8_t SubcarrierSpacing; + ///Cyclic prefix type [TS38.211 sec 4.2], 0: Normal; 1: Extended + uint8_t CyclicPrefix; + ///Starting OFDM symbol for the CORESET, Value: 0->13 + uint8_t StartSymbolIndex; +///Contiguous time duration of the CORESET in number of symbols. Corresponds to L1 parameter 𝑁𝑠𝑦𝑚𝑏_𝐶𝑂𝑅𝐸𝑆𝐸𝑇 [TS38.211 sec 7.3.2.2] Value: 1,2,3 + uint8_t DurationSymbols; + ///Frequency domain resources. This is a bitmap defining non-overlapping groups of 6 PRBs in ascending order. [TS38.213 10.1]. Also, corresponds to L1 parameter CORE SET RB N [TS38.211 sec 7.3.2.2] Bitmap of uint8 array. 45 bits. + uint8_t FreqDomainResource[6]; + ///CORESET-CCE-to-REG-mapping-type [TS38.211 sec 7.3.2.2] 0: non-interleaved 1: interleaved + uint8_t CceRegMappingType; + ///The number of REGs in a bundle. Must be 6 for cceRegMappingType = nonInterleaved. For cceRegMappingType = interleaved, must belong to {2,6} if duration = 1,2 and must belong to {3,6} if duration = 3. Corresponds to parameter L. [TS38.211 sec 7.3.2.2] Value: 2,3,6 + uint8_t RegBundleSize; + ///The interleaver size. For interleaved mapping belongs to {2,3,6} and for non-interleaved mapping is NA. Corresponds to parameter R. [TS38.211 sec 7.3.2.2] Value: 2,3,6 CoreSetType + uint8_t InterleaverSize; + ///[TS38.211 sec 7.3.2.2 and sec 7.4.1.3.2] 0: CORESET is configured by the PBCH or SIB1 (subcarrier 0 of CRB0 for DMRS mapping) 1: otherwise (subcarrier 0 of CORESET) + uint8_t CoreSetType; + ///[TS38.211 sec 7.3.2.2] Not applicable for non-interleaved mapping. For interleaved mapping and a PDCCH transmitted in a CORESET configured by the PBCH or SIB1 this should be set to phy cell ID. Value: 10 bits Otherwise, for interleaved mapping this is set to 0-> max num of PRBs. Value 0-> 275 + uint16_t ShiftIndex; + ///Granularity of precoding [TS38.211 sec 7.3.2.2] Field Type Description 0: sameAsRegBundle 1: allContiguousRBs + uint8_t precoderGranularity; + ///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot + uint16_t numDlDci; + ///The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535. + uint16_t RNTI[MAX_DCI_CORESET]; + ///For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535 + uint16_t ScramblingId[MAX_DCI_CORESET]; + ///For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535 + uint16_t ScramblingRNTI[MAX_DCI_CORESET]; + ///CCE start Index used to send the DCI Value: 0->135 + uint8_t CceIndex[MAX_DCI_CORESET]; + ///Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16 + uint8_t AggregationLevel[MAX_DCI_CORESET]; + ///Precoding and Beamforming structure See Table 3-43 + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET]; + ///PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps + uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET]; + ///PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB + uint8_t powerControlOffsetSS[MAX_DCI_CORESET]; +///The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BTYE_LEN*8 + uint16_t PayloadSizeBits[MAX_DCI_CORESET]; + ///DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB + uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN]; +} nfapi_nr_dl_tti_pdcch_pdu_rel15_t; + +typedef struct { + uint16_t pduBitmap; + uint16_t rnti; + uint16_t pduIndex; + // BWP [TS38.213 sec 12] + /// Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP, Value: 1->275 + uint16_t BWPSize; + /// bandwidth part start RB index from reference CRB [TS38.213 sec 12],Value: 0->274 + uint16_t BWPStart; + /// subcarrierSpacing [TS38.211 sec 4.2], Value:0->4 + uint8_t SubcarrierSpacing; + /// Cyclic prefix type [TS38.211 sec 4.2], 0: Normal; 1: Extended + uint8_t CyclicPrefix; + // Codeword information + /// Number of code words for this RNTI (UE), Value: 1 -> 2 + uint8_t NrOfCodewords; + /// Target coding rate [TS38.212 sec 5.4.2.1 and 38.214 sec 5.1.3.1]. This is the number of information bits per 1024 coded bits expressed in 0.1 bit units + uint16_t targetCodeRate[2]; + /// QAM modulation [TS38.212 sec 5.4.2.1 and 38.214 sec 5.1.3.1], Value: 2,4,6,8 + uint8_t qamModOrder[2]; + /// MCS index [TS38.214, sec 5.1.3.1], should match value sent in DCI Value : 0->31 + uint8_t mcsIndex[2]; + /// MCS-Table-PDSCH [TS38.214, sec 5.1.3.1] 0: notqam256, 1: qam256, 2: qam64LowSE + uint8_t mcsTable[2]; + /// Redundancy version index [TS38.212, Table 5.4.2.1-2 and 38.214, Table 5.1.2.1-2], should match value sent in DCI Value : 0->3 + uint8_t rvIndex[2]; + /// Transmit block size (in bytes) [TS38.214 sec 5.1.3.2], Value: 0->65535 + uint32_t TBSize[2]; + /// dataScramblingIdentityPdsch [TS38.211, sec 7.3.1.1], It equals the higher-layer parameter Datascrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id. Value: 0->65535 + uint16_t dataScramblingId; + /// Number of layers [TS38.211, sec 7.3.1.3]. Value : 1->8 + uint8_t nrOfLayers; + /// PDSCH transmission schemes [TS38.214, sec5.1.1] 0: Up to 8 transmission layers + uint8_t transmissionScheme; + /// Reference point for PDSCH DMRS "k" - used for tone mapping [TS38.211, sec 7.4.1.1.2] Resource block bundles [TS38.211, sec 7.3.1.6] Value: 0 -> 1 If 0, the 0 reference point for PDSCH DMRS is at Point A [TS38.211 sec 4.4.4.2]. Resource block bundles generated per sub-bullets 2 and 3 in [TS38.211, sec 7.3.1.6]. For sub-bullet 2, the start of bandwidth part must be set to the start of actual bandwidth part +NstartCORESET and the bandwidth of the bandwidth part must be set to the bandwidth of the initial bandwidth part. If 1, the DMRS reference point is at the lowest VRB/PRB of the allocation. Resource block bundles generated per sub-bullets 1 [TS38.211, sec 7.3.1.6] + uint8_t refPoint; + // DMRS [TS38.211 sec 7.4.1.1] + /// DMRS symbol positions [TS38.211, sec 7.4.1.1.2 and Tables 7.4.1.1.2-3 and 7.4.1.1.2-4] Bitmap occupying the 14 LSBs with: bit 0: first symbol and for each bit 0: no DMRS 1: DMRS + uint16_t dlDmrsSymbPos; + /// DL DMRS config type [TS38.211, sec 7.4.1.1.2] 0: type 1, 1: type 2 + uint8_t dmrsConfigType; + /// DL-DMRS-Scrambling-ID [TS38.211, sec 7.4.1.1.2 ] If provided by the higher-layer and the PDSCH is scheduled by PDCCH with CRC scrambled by CRNTI or CS-RNTI, otherwise, L2 should set this to physical cell id. Value: 0->65535 + uint16_t dlDmrsScramblingId; + /// DMRS sequence initialization [TS38.211, sec 7.4.1.1.2]. Should match what is sent in DCI 1_1, otherwise set to 0. Value : 0->1 + uint8_t SCID; + /// Number of DM-RS CDM groups without data [TS38.212 sec 7.3.1.2.2] [TS38.214 Table 4.1-1] it determines the ratio of PDSCH EPRE to DM-RS EPRE. Value: 1->3 + uint8_t numDmrsCdmGrpsNoData; + /// DMRS ports. [TS38.212 7.3.1.2.2] provides description between DCI 1-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + uint16_t dmrsPorts; + // Pdsch Allocation in frequency domain [TS38.214, sec 5.1.2.2] + /// Resource Allocation Type [TS38.214, sec 5.1.2.2] 0: Type 0, 1: Type 1 + uint8_t resourceAlloc; + /// For resource alloc type 0. TS 38.212 V15.0.x, 7.3.1.2.2 bitmap of RBs, 273 rounded up to multiple of 32. This bitmap is in units of VRBs. LSB of byte 0 of the bitmap represents the first RB of the bwp + uint8_t rbBitmap[36]; + /// For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The starting resource block within the BWP for this PDSCH. Value: 0->274 + uint16_t rbStart; + /// For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The number of resource block within for this PDSCH. Value: 1->275 + uint16_t rbSize; + /// VRB-to-PRB-mapping [TS38.211, sec 7.3.1.6] 0: non-interleaved 1: interleaved with RB size 2 2: Interleaved with RB size 4 + uint8_t VRBtoPRBMapping; + // Resource Allocation in time domain [TS38.214, sec 5.1.2.1] + /// Start symbol index of PDSCH mapping from the start of the slot, S. [TS38.214, Table 5.1.2.1-1] Value: 0->13 + uint8_t StartSymbolIndex; + /// PDSCH duration in symbols, L [TS38.214, Table 5.1.2.1-1] Value: 1->14 + uint8_t NrOfSymbols; + // PTRS [TS38.214, sec 5.1.6.3] + /// PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: antenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t PTRSPortIndex ; + /// PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4 + uint8_t PTRSTimeDensity; + /// PT-RS frequency density [TS38.214, table 5.1.6.3-2] 0: 2 1: 4 + uint8_t PTRSFreqDensity; + /// PT-RS resource element offset [TS38.211, table 7.4.1.2.2-1] Value: 0->3 + uint8_t PTRSReOffset; + /// PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3 + uint8_t nEpreRatioOfPDSCHToPTRS; + // Beamforming + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming; +}nfapi_nr_dl_tti_pdsch_pdu_rel15_t; + + +//for pdsch_pdu: +/* +typedef struct +{ + uint16_t target_code_rate;// + uint8_t qam_mod_order;// + uint8_t mcs_index;// + uint8_t mcs_table;// + uint8_t rv_index;// + uint32_t tb_size;// +} nfapi_nr_code_word_t; + +//table 3-38 +typedef struct +{ + uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs Bit 0: pdschPtrs - Indicates PTRS included (FR2) Bit 1:cbgRetxCtrl (Present when CBG based retransmit is used) All other bits reserved + uint16_t rnti;//The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535 + uint16_t pdu_index;// + uint16_t bwp_size;//Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP Value: 1->275 + uint16_t bwp_start;//bandwidth part start RB index from reference CRB [TS38.213 sec 12] Value: 0->274 + uint8_t subcarrier_spacing;//Value:0->4 + uint8_t cyclic_prefix;//0: Normal; 1: Extended + uint8_t nr_of_code_words;//Number of code words for this RNTI (UE) Value: 1 -> 2 + nfapi_nr_code_word_t* code_word_list; + uint16_t data_scrambling_id;// + uint8_t nr_of_layers;// + uint8_t transmission_scheme;//PDSCH transmission schemes [TS38.214, sec 5.1.1] 0: Up to 8 transmission layers + uint8_t ref_point;//Reference point for PDSCH DMRS "k" - used for tone mapping + //DMRS + uint16_t dl_dmrs_symb_pos;//Bitmap occupying the 14 LSBs with: bit 0: first symbol and for each bit 0: no DMRS 1: DMRS + uint8_t dmrs_config_type;//DL DMRS config type[TS38.211, sec 7.4.1.1.2] 0: type 1 1: type 2 + uint16_t dl_dmrs_scrambling_id;//DL-DMRS-Scrambling-ID [TS38.211, sec 7.4.1.1.2 ] If provided by the higher-layer and the PDSCH is scheduled by PDCCH with CRC scrambled by CRNTI or CS-RNTI, otherwise, L2 should set this to physical cell id. Value: 0->65535 + uint8_t scid;// 0 1 + uint8_t num_dmrs_cdm_grps_no_data;//Number of DM-RS CDM groups without data [TS38.212 sec 7.3.1.2.2] [TS38.214 Table 4.1-1] it determines the ratio of PDSCH EPRE to DM-RS EPRE. Value: 1->3 + uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.2.2] provides description between DCI 1-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + + //Pdsch Allocation in frequency domain [TS38.214, sec 5.1.2.2] + uint8_t resource_alloc;//Resource Allocation Type [TS38.214, sec 5.1.2.2] 0: Type 0 1: Type 1 + uint8_t rb_bit_map[36];//For resource alloc type 0. TS 38.212 V15.0.x, 7.3.1.2.2 bitmap of RBs, 273 rounded up to multiple of 32. This bitmap is in units of VRBs. LSB of byte 0 of the bitmap represents the first RB of the bwp + uint16_t rb_start;//For resource allocation type 1. [TS38.214, sec5.1.2.2.2] The starting resource block within the BWP for this PDSCH. Value: 0->274 + uint16_t rb_size;//For resource allocation type 1. [TS38.214, sec 5.1.2.2.2] The number of resource block within for this PDSCH. Value: 1->275 + uint8_t vrb_to_prb_mapping;//VRB-to-PRB-mapping [TS38.211, sec 7.3.1.6] 0: non-interleaved 1: interleaved with RB size 2 2: Interleaved with RB size 4 + //Resource Allocation in time domain [TS38.214, sec 5.1.2.1] + uint8_t start_symbol_index;//Start symbol index of PDSCH mapping from the start of the slot, S. [TS38.214, Table 5.1.2.1-1] Value: 0->13 + uint8_t nr_of_symbols;//PDSCH duration in symbols, L [TS38.214, Table 5.1.2.1-1] Value: 1->14 + //PTRS TS38.214 sec 5.1.6.3 + uint8_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: ntenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t ptrs_time_density;//PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4 + uint8_t ptrs_freq_density;//PT-RS frequency density [TS38.214, table[5.1.6.3-2] 0: 2 1: 4 + uint8_t ptrs_re_offset;//PT-RS resource element offset [TS38.211, table [7.4.1.2.2-1] + uint8_t n_epre_ratio_of_pdsch_to_ptrs;//PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3 + nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list; + //TX power info + uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE [TS38.214, sec 5.2.2.3.1] Value :0->23 representing -8 to 15 dB in 1dB steps + uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES [TS38.214, sec 5.2.2.3.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + //CBG fields + uint8_t is_last_cb_present;//Indicates whether last CB is present in the CBG retransmission 0: CBG retransmission does not include last CB 1: CBG retransmission includes last CB If CBG Re-Tx includes last CB, L1 will add the TB CRC to the last CB in the payload before it is read into the LDPC HW unit + uint8_t is_inline_tb_crc;//Indicates whether TB CRC is part of data payload or control message 0: TB CRC is part of data payload 1: TB CRC is part of control message + uint32_t dl_tb_crc;//TB CRC: to be used in the last CB, applicable only if last CB is present + +} nfapi_nr_dlsch_pdu_t; +*/ + +//for csi-rs_pdu: + +//table 3-39 +typedef struct +{ + uint16_t bwp_size;// + uint16_t bwp_start;// + uint8_t subcarrier_spacing;// + uint8_t cyclic_prefix;// + uint16_t start_rb; + uint16_t nr_of_rbs; + uint8_t csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP + uint8_t row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18 + uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter + uint8_t symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13 + uint8_t symb_l1;// + uint8_t cdm_type; + uint8_t freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three + uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023 + //tx power info + uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE Value :0->23 representing -8 to 15 dB in 1dB steps + uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB + +} nfapi_nr_dl_tti_csi_rs_pdu_rel15_t; + +//for ssb_pdu: + +typedef struct +{ + uint32_t bch_payload;//BCH payload. The valid bits are indicated in the PARAM/CONFIG TLVs. If PARAM/CONFIG TLVs indicate MAC generates full bchPayload then the payload length is 31 bits with the 8 LSB bits being. Otherwise timing PBCH bits are generated by the PHY. And for bchPayload the 24 LSB are used. + +} nfapi_nr_mac_generated_mib_pdu_t; + +typedef struct +{ + uint8_t dmrs_type_a_position;//The position of the first DM-RS for downlink and uplink. + uint8_t pdcch_config_sib1;//The parameter PDCCH-ConfigSIB1 that determines a common ControlResourceSet (CORESET) a common search space and necessary PDCCH parameters. + uint8_t cell_barred;//The flag to indicate whether the cell is barred + uint8_t intra_freq_reselection;//The flag to controls cell selection/reselection to intrafrequency cells when the highest ranked cell is barred, or treated as barred by the UE. value 0 1 + +} nfapi_nr_phy_generated_mib_pdu_t; + + +typedef struct +{ + nfapi_nr_mac_generated_mib_pdu_t* mac_generated_mib_pdu; + nfapi_nr_phy_generated_mib_pdu_t* phy_generated_mib_pdu; + +} nfapi_nr_bch_payload_t; + +typedef struct { + /// Physical Cell ID Value 0~>1007 + uint16_t PhysCellId; + ///PSS EPRE to SSS EPRE in a SS/PBCH block 0 = 0dB 1 = 3dB + uint8_t BetaPss; + ///SS/PBCH block index within a SSB burst set. Required for PBCH DMRS scrambling. Value: 0->63 (Lmax) + uint8_t SsbBlockIndex; + /// ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (TS38.211, section 7.4.3.1) Value: 0->31 + uint8_t SsbSubcarrierOffset; + ///Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Value: 0->2199 + uint16_t ssbOffsetPointA; + /// A value indicating how the BCH payload is generated. This should match the PARAM/CONFIG TLVs. Value: 0: MAC generates the full PBCH payload, see Table 3-41, where bchPayload has 31 bits 1: PHY generates the timing PBCH bits, see Table 3-41, where the bchPayload has 24 bits 2: PHY generates the full PBCH payload + uint8_t bchPayloadFlag; + uint32_t bchPayload; + nfapi_nr_tx_precoding_and_beamforming_t precoding_and_beamforming; +} nfapi_nr_dl_tti_ssb_pdu_rel15_t; + +typedef struct { + nfapi_nr_dl_tti_ssb_pdu_rel15_t ssb_pdu_rel15; +} nfapi_nr_dl_tti_ssb_pdu; + +typedef struct { + nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_rs_pdu_rel15; +} nfapi_nr_dl_tti_csi_rs_pdu; + +typedef struct { + nfapi_nr_dl_tti_pdsch_pdu_rel15_t pdsch_pdu_rel15; +} nfapi_nr_dl_tti_pdsch_pdu; + +typedef struct { + nfapi_nr_dl_tti_pdcch_pdu_rel15_t pdcch_pdu_rel15; +} nfapi_nr_dl_tti_pdcch_pdu; + +typedef struct { + uint16_t PDUType; + uint16_t PDUSize; + + union { + nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu; + nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu; + nfapi_nr_dl_tti_csi_rs_pdu csi_rs_pdu; + nfapi_nr_dl_tti_ssb_pdu ssb_pdu; + }; +} nfapi_nr_dl_tti_request_pdu_t; + +#define NFAPI_NR_MAX_DL_TTI_PDUS 32 +typedef struct { + /// Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t nPDUs; + /// Number of UEs in the Group included in this message. Value 0 -> 255 + uint8_t nGroup; + /// List containing PDUs + nfapi_nr_dl_tti_request_pdu_t dl_tti_pdu_list[NFAPI_NR_MAX_DL_TTI_PDUS]; + /// Number of UE in this group. For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 12 + uint8_t nUe[256]; + /// This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255 + uint8_t PduIdx[256][12]; +} nfapi_nr_dl_tti_request_body_t; + +typedef struct { + nfapi_p7_message_header_t header; + /// System Frame Number (0-1023) + uint16_t SFN; + /// Slot number (0-319) + uint16_t Slot; + nfapi_nr_dl_tti_request_body_t dl_tti_request_body; + nfapi_vendor_extension_tlv_t vendor_extension; +} nfapi_nr_dl_tti_request_t; + +/* +typedef struct +{ + nfapi_nr_dl_tti_pdcch_pdu* pdcch_pdu; + nfapi_nr_dl_tti_pdsch_pdu* pdsch_pdu; + nfapi_nr_dl_tti_csi_rs_pdu_t* csi_rs_pdu; + nfapi_nr_dl_tti_ssb_pdu_t* ssb_pdu; +} nfapi_nr_dl_pdu_configuration_t; +*/ + /* +typedef struct +{ + uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU, + uint16_t pdu_size;//Size of the PDU control information (in bytes). This length value includes the 4 bytes required for the PDU type and PDU size parameters. Value 0 -> 65535 + nfapi_nr_dl_pdu_configuration_t* dl_pdu_configuration; + +} nfapi_nr_dl_tti_request_number_of_pdus_t; + + +typedef struct +{ + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255 + +} nfapi_nr_dl_tti_request_number_of_ue_t; + +typedef struct +{ + uint8_t n_ue;//Number of UE in this group For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 12 + nfapi_nr_dl_tti_request_number_of_ue_t* ue_list; + +} nfapi_nr_dl_tti_request_number_of_groups_t; + +//3.4.2 dl_tti_request +typedef struct { + uint16_t sfn; //0->1023 + uint16_t slot;//0->319 + uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t n_group;//Number of UE Groups included in this message. Value 0 -> 255 + nfapi_nr_dl_tti_request_number_of_pdus_t* pdus_list; + nfapi_nr_dl_tti_request_number_of_groups_t* groups_list; + +} nfapi_nr_dl_tti_request_t; +*/ + +// Section 3.4.3 ul_tti_request + +//for prach_pdu: +typedef struct +{ + nfapi_nr_dig_bf_interface_t* dig_bf_interface_list; + +} nfapi_nr_ul_beamforming_number_of_prgs_t; + +typedef struct +{ + uint16_t num_prgs; + uint16_t prg_size; + //watchout: dig_bf_interface here, in table 3-43 it's dig_bf_interfaces + uint8_t dig_bf_interface; + nfapi_nr_ul_beamforming_number_of_prgs_t* prgs_list;// + +} nfapi_nr_ul_beamforming_t; + +typedef struct +{ + uint16_t phys_cell_id; + uint8_t num_prach_ocas; + uint8_t prach_format; + uint8_t num_ra; + uint8_t prach_start_symbol; + uint16_t num_cs;// + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_prach_pdu_t; + +//for pusch_pdu: + + //for nfapi_nr_pusch_data_t; +typedef struct +{ + uint8_t rv_index; + uint8_t harq_process_id; + uint8_t new_data_indicator; + uint32_t tb_size; + uint16_t num_cb; + uint8_t cb_present_and_position[(NFAPI_MAX_NUM_CB+7) / 8]; + +} nfapi_nr_pusch_data_t; + //for nfapi_nr_pusch_uci_t +typedef struct +{ + uint16_t harq_ack_bit_length; + uint16_t csi_part1_bit_length; + uint16_t csi_part2_bit_length; + uint8_t alpha_scaling; + uint8_t beta_offset_harq_ack; + uint8_t beta_offset_csi1; + uint8_t beta_offset_csi2; + +} nfapi_nr_pusch_uci_t; + + //for nfapi_nr_pusch_ptrs_t +typedef struct +{ + uint16_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec6.2.3.1 and 38.212, section 7.3.1.1.2] Bitmap occupying the 12 LSBs with: bit 0: antenna port 0 bit 11: antenna port 11 and for each bit 0: PTRS port not used 1: PTRS port used + uint8_t ptrs_dmrs_port;//DMRS port corresponding to PTRS. + uint8_t ptrs_re_offset;//PT-RS resource element offset value taken from 0~11 +} nfapi_nr_ptrs_ports_t; + +typedef struct +{ + uint8_t num_ptrs_ports; + nfapi_nr_ptrs_ports_t* ptrs_ports_list; + uint8_t ptrs_time_density; + uint8_t ptrs_freq_density; + uint8_t ul_ptrs_power; + +}nfapi_nr_pusch_ptrs_t; + + //for nfapi_nr_dfts_ofdm_t +typedef struct +{ + uint8_t low_papr_group_number;//Group number for Low PAPR sequence generation. + uint16_t low_papr_sequence_number;//[TS38.211, sec 5.2.2] For DFT-S-OFDM. + uint8_t ul_ptrs_sample_density;//Number of PTRS groups [But I suppose this sentence is misplaced, so as the next one. --Chenyu] + uint8_t ul_ptrs_time_density_transform_precoding;//Number of samples per PTRS group + +} nfapi_nr_dfts_ofdm_t; + +#define PUSCH_PDU_BITMAP_PUSCH_DATA 0x1 +#define PUSCH_PDU_BITMAP_PUSCH_UCI 0x2 +#define PUSCH_PDU_BITMAP_PUSCH_PTRS 0x4 +#define PUSCH_PDU_BITMAP_DFTS_OFDM 0x8 + +typedef struct +{ + uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs (see above) + uint16_t rnti; + uint32_t handle;//An opaque handling returned in the RxData.indication and/or UCI.indication message + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + //pusch information always include + uint16_t target_code_rate; + uint8_t qam_mod_order; + uint8_t mcs_index; + uint8_t mcs_table; + uint8_t transform_precoding; + uint16_t data_scrambling_id; + uint8_t nrOfLayers; + //DMRS + uint8_t ul_dmrs_symb_pos; + uint8_t dmrs_config_type; + uint16_t ul_dmrs_scrambling_id; + uint8_t scid;// + uint8_t num_dmrs_cdm_grps_no_data; + uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + uint8_t resource_alloc; + uint8_t rb_bitmap[36];// + uint16_t rb_start; + uint16_t rb_size; + uint8_t vrb_to_prb_mapping; + uint8_t frequency_hopping; + uint16_t tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + uint8_t uplink_frequency_shift_7p5khz; + //Resource Allocation in time domain + uint8_t start_symbol_index; + uint8_t nr_of_symbols; + //Optional Data only included if indicated in pduBitmap + nfapi_nr_pusch_data_t pusch_data; + nfapi_nr_pusch_uci_t pusch_uci; + nfapi_nr_pusch_ptrs_t pusch_ptrs; + nfapi_nr_dfts_ofdm_t dfts_ofdm; + //beamforming + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_pusch_pdu_t; + +//for pucch_pdu: +typedef struct +{ + uint16_t rnti; + uint32_t handle; + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + + uint8_t format_type; + uint8_t multi_slot_tx_indicator; + uint8_t pi_2bpsk; + //pucch allocation in freq domain + uint16_t prb_start; + uint16_t prb_size; + //pucch allocation in tome domain + uint8_t start_symbol_index; + uint8_t nr_of_symbols; + //hopping info + uint8_t freq_hop_flag; + uint16_t second_hop_prb; + uint8_t group_hop_flag; + uint8_t sequence_hop_flag; + uint16_t hopping_id; + uint16_t initial_cyclic_shift; + + uint16_t data_scrambling_id; + uint8_t time_domain_occ_idx; + uint8_t pre_dft_occ_idx; + uint8_t pre_dft_occ_len; + //DMRS + uint8_t add_dmrs_flag; + uint16_t dmrs_scrambling_id; + uint8_t dmrs_cyclic_shift; + + uint8_t sr_flag; + uint8_t bit_len_harq; + uint16_t bit_len_csi_part1; + uint16_t bit_len_csi_part2; + + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_pucch_pdu_t; + +//for srs_pdu: + +typedef struct +{ + uint16_t rnti;//UE RNTI + uint32_t handle;//An opaque handling returned in the SRS.indication + //BWP + uint16_t bwp_size; + uint16_t bwp_start; + uint8_t subcarrier_spacing; + uint8_t cyclic_prefix; + + uint8_t num_ant_ports; + uint8_t num_symbols; + uint8_t num_repetitions; + uint8_t time_start_position;//Starting position in the time domain l0; Note: the MAC undertakes the translation from startPosition to 𝑙0 + uint8_t config_index; + uint16_t sequence_id; + uint8_t bandwidth_index; + uint8_t comb_size; + uint8_t comb_offset;//Transmission comb offset 𝑘 ̄ TC [TS38.211, Sec 6.4.1.4.3] Value: 0 → 1 (combSize = 0) Value: 0 → 3 (combSize = 1) + uint8_t cyclic_shift; + uint8_t frequency_position; + uint8_t frequency_shift; + uint8_t frequency_hopping; + uint8_t group_or_sequence_hopping;//Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRS-Resource + uint8_t resource_type;//Type of SRS resource allocation + uint16_t t_srs;//SRS-Periodicity in slots [TS38.211 Sec 6.4.1.4.4] Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 + uint16_t t_offset;//Slot offset value [TS38.211, Sec 6.4.1.4.3] Value:0->2559 + + nfapi_nr_ul_beamforming_t beamforming; + +} nfapi_nr_srs_pdu_t; + +// + +typedef enum { + NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE = 0, + NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE = 1, + NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE = 2, + NFAPI_NR_DL_TTI_SSB_PDU_TYPE = 3, +} nfapi_nr_dl_tti_pdu_type_e; + +typedef enum { + NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE=0, + NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE, + NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE, + NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE, +} nfapi_nr_ul_config_pdu_type_e; + +typedef struct +{ + uint16_t pdu_type;//0: PRACH PDU, 1: PUSCH PDU, 2: PUCCH PDU, 3: SRS PDU + uint16_t pdu_size;//Value: 0 -> 65535 + union + { + nfapi_nr_prach_pdu_t prach_pdu; + nfapi_nr_pusch_pdu_t pusch_pdu; + nfapi_nr_pucch_pdu_t pucch_pdu; + nfapi_nr_srs_pdu_t srs_pdu; + }; + +} nfapi_nr_ul_tti_request_number_of_pdus_t; + +typedef struct +{ + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 65535 + +} nfapi_nr_ul_tti_request_number_of_ue_t; + +typedef struct +{ + uint8_t n_ue;//Number of UE in this group For SU-MIMO, one group includes one UE only. For MU-MIMO, one group includes up to 12 UEs. Value 1 -> 6 + nfapi_nr_ul_tti_request_number_of_ue_t ue_list[NFAPI_MAX_NUM_UL_UE_PER_GROUP]; + +} nfapi_nr_ul_tti_request_number_of_groups_t; + +typedef struct { + uint16_t SFN; //0->1023 + uint16_t Slot;//0->319 + uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255 + uint8_t rach_present;//Indicates if a RACH PDU will be included in this message. 0: no RACH in this slot 1: RACH in this slot + uint8_t n_ulsch;//Number of ULSCH PDUs that are included in this message. + uint8_t n_ulcch;//Number of ULCCH PDUs + uint8_t n_group;//Number of UE Groups included in this message. Value 0 -> 8 + nfapi_nr_ul_tti_request_number_of_pdus_t pdus_list[NFAPI_MAX_NUM_UL_PDU]; + nfapi_nr_ul_tti_request_number_of_groups_t groups_list[NFAPI_MAX_NUM_GROUPS]; +} nfapi_nr_ul_tti_request_t; + +//3.4.4 ul_dci_request + +//table 3-54 + +/* +typedef struct +{ + uint16_t pdu_type;//0: PDCCH PDU + uint16_t pdu_size; + nfapi_nr_dl_pdu_configuration_t* phcch_pdu_configuration; + +} nfapi_nr_ul_dci_request_number_of_pdus_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t num_pdus; + nfapi_nr_ul_dci_request_number_of_pdus_t* pdu_list; + +} nfapi_nr_ul_dci_request_t; +*/ + + // normally one PDU per coreset per BWP +#define NFAPI_NR_MAX_UL_DCI_PDUS 4 + +typedef struct { + /// only possible value 0: PDCCH PDU + uint16_t PDUType; + ///Size of the PDU control information (in bytes). This length value includes the 4 bytes required for the PDU type and PDU size parameters. Value 0 -> 65535 + uint16_t PDUSize; + nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu; +} nfapi_nr_ul_dci_request_pdus_t; + +typedef struct { + uint16_t SFN; + uint16_t Slot; + uint8_t numPdus; + nfapi_nr_ul_dci_request_pdus_t ul_dci_pdu_list[NFAPI_NR_MAX_UL_DCI_PDUS]; +} nfapi_nr_ul_dci_request_t; + +//3.4.5 slot_errors +typedef enum { + NFAPI_NR_SLOT_UL_TTI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_UL_TTI_SFN_OUT_OF_SYNC, + NFAPI_NR_SLOT_UL_TTI_MSG_BCH_MISSING, + NFAPI_NR_SLOT_UL_TTI_MSG_SLOT_ERR + +} nfapi_nr_slot_errors_ul_tti_e; + +typedef enum { + NFAPI_NR_SLOT_DL_TTI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_DL_TTI_MSG_SLOT_ERR + +} nfapi_nr_slot_errors_dl_tti_e; + + +typedef enum { + NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_STATE, + NFAPI_NR_SLOT_UL_DCI_MSG_INVALID_SFN, + NFAPI_NR_SLOT_UL_DCI_MSG_UL_DCI_ERR + +} nfapi_nr_slot_errors_ul_dci_e; + +//3.4.6 tx_data_request + +//table 3-58 +#define NFAPI_NR_MAX_TX_REQUEST_TLV 2 +typedef struct +{ + uint16_t PDU_length; + uint16_t PDU_index; + uint32_t num_TLV; + nfapi_nr_tx_data_request_tlv_t TLVs[NFAPI_NR_MAX_TX_REQUEST_TLV]; + +} nfapi_nr_pdu_t; + +#define NFAPI_NR_MAX_TX_REQUEST_PDUS 16 +typedef struct +{ + uint16_t SFN; + uint16_t Slot; + uint16_t Number_of_PDUs; + nfapi_nr_pdu_t pdu_list[NFAPI_NR_MAX_TX_REQUEST_PDUS]; + +} nfapi_nr_tx_data_request_t; + +typedef enum { + NFAPI_NR_DL_DATA_MSG_INVALID_STATE, + NFAPI_NR_DL_DATA_MSG_INVALID_SFN, + NFAPI_NR_DL_DATA_MSG_TX_ERR + +} nfapi_nr_dl_data_errors_e; + +//section 3.4.7 rx_data_indication + +//table 3-61 + +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint8_t harq_id; + uint16_t pdu_length; + uint8_t ul_cqi; + uint16_t timing_advance;//Timing advance 𝑇𝐴 measured for the UE [TS 38.213, Section 4.2] NTA_new = NTA_old + (TA − 31) ⋅ 16 ⋅ 64⁄2μ Value: 0 → 63 0xffff should be set if this field is invalid + uint16_t rssi; + //variable ! fixme + uint32_t pdu; //MAC PDU + +} nfapi_nr_rx_data_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t number_of_pdus; + nfapi_nr_rx_data_pdu_t* pdu_list; + +} nfapi_nr_rx_data_indication_t; + +//3.4.8 crc_indication +//table 3-62 +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint8_t harq_id; + uint8_t tb_crc_status; + uint16_t num_cb;//If CBG is not used this parameter can be set to zero. Otherwise the number of CBs in the TB. Value: 0->65535 + //! fixme + uint8_t* cb_crc_status;//cb_crc_status[ceil(NumCb/8)]; + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + +} nfapi_nr_crc_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t number_crcs; + nfapi_nr_crc_t* crc_list; + +} nfapi_nr_crc_indication_t; + +//3.4.9 uci_indication + +//table 3-67 +typedef struct +{ + uint8_t sr_indication; + uint8_t sr_confidence_level; + +} nfapi_nr_sr_pdu_0_1_t; +//table 3-69 +typedef struct +{ + uint16_t sr_bit_len; + //! fixme + uint8_t* sr_payload;//sr_payload[ceil(sr_bit_len/8)]; + +} nfapi_nr_sr_pdu_2_3_4_t; +//table 3-68 +typedef struct +{ + uint8_t harq_value;//Indicates result on HARQ data. Value: 0 = pass 1 = fail 2 = not present + +} nfapi_nr_harq_t; + +//table 3-70 +typedef struct +{ + uint8_t harq_crc; + uint16_t harq_bit_len; + //! fixme + uint8_t* harq_payload;//harq_payload[ceil(harq_bit_len)]; +} nfapi_nr_harq_pdu_2_3_4_t; + +typedef struct +{ + uint8_t num_harq; + uint8_t harq_confidence_level; + nfapi_nr_harq_t* harq_list; + +} nfapi_nr_harq_pdu_0_1_t; + +//table 3-71 +typedef struct +{ + uint8_t csi_part1_crc; + uint16_t csi_part1_bit_len; + //! fixme + uint8_t* csi_part1_payload;//uint8_t[ceil(csiPart1BitLen/8)] + +} nfapi_nr_csi_part1_pdu_t; + +//table 3-72 +typedef struct +{ + uint8_t csi_part2_crc; + uint16_t csi_part2_bit_len; + //! fixme + uint8_t* csi_part2_payload;//uint8_t[ceil(csiPart2BitLen/8)] +} nfapi_nr_csi_part2_pdu_t; + +//table 3-63 + + //for dci_pusch_pdu +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_harq_pdu_2_3_4_t harq;//table 3-70 + nfapi_nr_csi_part1_pdu_t csi_part1;//71 + nfapi_nr_csi_part2_pdu_t csi_part2;//72 + +}nfapi_nr_uci_pusch_pdu_t; + +//for PUCCH PDU Format 0/1 +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t pucch_format;//PUCCH format Value: 0 -> 1 0: PUCCH Format0 1: PUCCH Format1 + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_sr_pdu_0_1_t sr;//67 + nfapi_nr_harq_pdu_0_1_t harq;//68 + + +}nfapi_nr_uci_pucch_pdu_format_0_1_t; + +//PUCCH PDU Format 2/3/4 +typedef struct +{ + uint8_t pdu_bit_map; + uint32_t handle; + uint16_t rnti; + uint8_t pucch_format;//PUCCH format Value: 0 -> 2 0: PUCCH Format2 1: PUCCH Format3 2: PUCCH Format4 + uint8_t ul_cqi; + uint16_t timing_advance; + uint16_t rssi; + nfapi_nr_sr_pdu_2_3_4_t sr;//69 + nfapi_nr_harq_pdu_2_3_4_t harq;//70 + nfapi_nr_csi_part1_pdu_t csi_part1;//71 + nfapi_nr_csi_part2_pdu_t csi_part2;//72 + +}nfapi_nr_uci_pucch_pdu_format_2_3_4_t; + +//for SR, HARQ and CSI Part 1/ 2 PDUs + +typedef struct +{ + nfapi_nr_uci_pusch_pdu_t* pusch_pdu; + nfapi_nr_uci_pucch_pdu_format_0_1_t* pucch_pdu_format_0_1; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t* pucch_pdu_format_2_3_4; + nfapi_nr_sr_pdu_0_1_t* sr_pdu_0_1; + nfapi_nr_sr_pdu_2_3_4_t* sr_pdu_2_3_4; + nfapi_nr_harq_pdu_0_1_t* harq_pdu_0_1; + nfapi_nr_harq_pdu_2_3_4_t* harq_pdu_2_3_4; + nfapi_nr_csi_part1_pdu_t* csi_part1_pdu; + nfapi_nr_csi_part2_pdu_t* csi_part2_pdu; + +} nfapi_nr_uci_pdu_information_t; + +typedef struct +{ + uint16_t pdu_type; + uint16_t pdu_size; + nfapi_nr_uci_pdu_information_t uci_pdu; + +} nfapi_nr_uci_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint16_t num_ucis; + nfapi_nr_uci_t* uci_list; + +} nfapi_nr_uci_indication_t; + +//3.4.10 srs_indication +//table 3-73 + +typedef struct +{ + uint8_t rb_snr; +}nfapi_nr_srs_indication_reported_symbol_resource_block_t; + +typedef struct +{ + uint16_t num_rbs; + nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list; +}nfapi_nr_srs_indication_reported_symbol_t; + + +typedef struct +{ + uint32_t handle; + uint16_t rnti; + uint16_t timing_advance; + uint8_t num_symbols; + uint8_t wide_band_snr; + uint8_t num_reported_symbols; + nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list; + +}nfapi_nr_srs_indication_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t number_of_pdus; + nfapi_nr_srs_indication_pdu_t* pdu_list; + +} nfapi_nr_srs_indication_t; + + +//3.4.11 rach_indication +//table 3-74 +typedef struct +{ + uint8_t preamble_index; + uint16_t timing_advance; + uint32_t preamble_pwr; + +} nfapi_nr_prach_indication_preamble_t; + +typedef struct{ + uint16_t phy_cell_id; + uint8_t symbol_index; + uint8_t slot_index; + uint8_t freq_index; + uint8_t avg_rssi; + uint8_t avg_snr; + uint8_t num_preamble; + nfapi_nr_prach_indication_preamble_t* preamble_list; + +}nfapi_nr_prach_indication_pdu_t; + +typedef struct +{ + uint16_t sfn; + uint16_t slot; + uint8_t number_of_pdus; + nfapi_nr_prach_indication_pdu_t* pdu_list; + +} nfapi_nr_rach_indication_t; + +#endif diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 5d463afdae..5abf6b75c3 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -18,7 +18,8 @@ #define _NFAPI_VNF_INTERFACE_H_ #include "nfapi_interface.h" -#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" + #include "debug.h" #include "netinet/in.h" @@ -938,7 +939,7 @@ int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id); * may be released after this function call has returned or at a later pointer */ int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req); -int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_config_request_t* req); +int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req); /*! Send the UL_CONFIG.request * \param config A pointer to the vnf p7 configuration diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index 8b60122483..35bd5e4c1b 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -482,7 +482,7 @@ int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_re return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header); } -int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_config_request_t* req) +int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req); diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 6db9548dbe..ed8dd3b49a 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -23,13 +23,14 @@ #include #include #include - #include "assertions.h" #include "SIMULATION/TOOLS/sim.h" #include "PHY/CODING/nrLDPC_encoder/defs.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #define MAX_NUM_DLSCH_SEGMENTS 16 +#define MAX_BLOCK_LENGTH 8448 #ifndef malloc16 # ifdef __AVX2__ @@ -42,7 +43,6 @@ #define NR_LDPC_PROFILER_DETAIL #define NR_LDPC_ENABLE_PARITY_CHECK - // 4-bit quantizer char quantize4bit(double D,double x) { @@ -76,31 +76,15 @@ char quantize8bit(double D,double x) return((char)qxd); } -char quantize(double D,double x,unsigned char B) -{ - double qxd; - short maxlev; - qxd = floor(x/D); - - maxlev = 1<<(B-1);//(char)(pow(2,B-1)); - - //printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev); - - if (qxd <= -maxlev) - qxd = -maxlev; - else if (qxd >= maxlev) - qxd = maxlev-1; - - return((char)qxd); -} - typedef struct { -double n_iter_mean; -double n_iter_std; -int n_iter_max; + double n_iter_mean; + double n_iter_std; + int n_iter_max; } n_iter_stats_t; -#define MAX_BLOCK_LENGTH 8448 +RAN_CONTEXT_t RC; +PHY_VARS_UE ***PHY_vars_UE_g; +uint16_t NB_UE_INST = 1; short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; @@ -118,7 +102,7 @@ int test_ldpc(short No_iteration, unsigned int *crc_misses, time_stats_t *time_optim, time_stats_t *time_decoder, - n_iter_stats_t * dec_iter) + n_iter_stats_t *dec_iter) { //clock initiate //time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder; @@ -146,12 +130,12 @@ int test_ldpc(short No_iteration, double *modulated_input[MAX_NUM_DLSCH_SEGMENTS]; char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS]; unsigned int i,j,trial=0; - short BG,Zc,Kb,nrows;//,ncols; + short BG=0,nrows=0;//,ncols; int no_punctured_columns,removed_bit; - int i1; + int i1,Zc,Kb=0; int R_ind = 0; //Table of possible lifting sizes -//short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; + //short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; //int n_segments=1; int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89}; //double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88}; @@ -227,15 +211,15 @@ int test_ldpc(short No_iteration, //determine number of bits in codeword if (block_length>3840) { - BG=1; + BG = 1; Kb = 22; - nrows=46; //parity check bits + nrows = 46; //parity check bits //ncols=22; //info bits } else if (block_length<=3840) { - BG=2; - nrows=42; //parity check bits + BG = 2; + nrows = 42; //parity check bits //ncols=10; // info bits if (block_length>640) @@ -246,7 +230,7 @@ int test_ldpc(short No_iteration, Kb = 8; else Kb = 6; - } + } if (nom_rate == 1) if (denom_rate == 5) @@ -298,12 +282,12 @@ int test_ldpc(short No_iteration, } } - printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length,BG, Zc, Kb); + printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length, BG, Zc, Kb); no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc; // printf("puncture:%d\n",no_punctured_columns); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate)); if (ntrials==0) - ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1); + ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1); for (trial=0; trial < ntrials; trial++) { @@ -311,30 +295,30 @@ int test_ldpc(short No_iteration, //// encoder start_meas(&time); for(j=0;j3840) { - BG=1; + BG = 1; Kb = 22; //nrows=46; //parity check bits //ncols=22; //info bits } else if (block_length<=3840) { - BG=2; + BG = 2; //nrows=42; //parity check bits //ncols=10; // info bits @@ -663,8 +646,7 @@ int main(int argc, char *argv[]) fprintf(fd,"SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX\n"); - for (SNR=SNR0;SNRn_iter_mean); printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std); printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max); @@ -720,23 +702,11 @@ int main(int argc, char *argv[]) dec_iter->n_iter_max ); - if (decoded_errors[i] == 0) - break; + if (decoded_errors[i] == 0) break; + i=i+1; - - } fclose(fd); return(0); } - - - - - - - - - - diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 76cde6c3be..cb3f427f24 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -11,6 +11,7 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h" #include "PHY/CODING/coding_defs.h" #include "SIMULATION/TOOLS/sim.h" +#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" //#include "PHY/NR_TRANSPORT/nr_transport.h" //#include "common/utils/LOG/log.h" @@ -18,7 +19,12 @@ //#define DEBUG_POLAR_TIMING //#define DEBUG_POLARTEST -int main(int argc, char *argv[]) { +RAN_CONTEXT_t RC; +PHY_VARS_UE ***PHY_vars_UE_g; +uint16_t NB_UE_INST = 1; + +int main(int argc, char *argv[]) +{ //Default simulation values (Aim for iterations = 1000000.) int decoder_int16=0; int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI @@ -169,7 +175,7 @@ if (logFlag){ double channelOutput[coderLength]; //add noise int16_t channelOutput_int16[coderLength]; - t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level); + t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, 1, aggregation_level,NULL); #ifdef DEBUG_DCI_POLAR_PARAMS uint32_t dci_pdu[4]; @@ -235,8 +241,8 @@ if (logFlag){ start_meas(&timeEncoder); if (decoder_int16==1) { - polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, currentPtr); - //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr); + polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, currentPtr); + //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr); } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) polar_encoder(testInput, encoderOutput, currentPtr); @@ -272,7 +278,7 @@ if (logFlag){ start_meas(&timeDecoder); if (decoder_int16==1) { - decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, currentPtr); + decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, currentPtr); } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI if (polarMessageType == 0) { decoderState = polar_decoder(channelOutput, diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c index ee1a228ab8..02d5dc64e0 100644 --- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c +++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c @@ -1,27 +1,16 @@ -#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" -#include "SIMULATION/TOOLS/sim.h" #include +#include "SIMULATION/TOOLS/sim.h" +#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h" +#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" //#define DEBUG_SMALLBLOCKTEST -signed char quantize(double D, double x, unsigned char B) +RAN_CONTEXT_t RC; +PHY_VARS_UE ***PHY_vars_UE_g; +uint16_t NB_UE_INST = 1; + +int main(int argc, char *argv[]) { - double qxd; - short maxlev; - qxd = floor(x/D); - - maxlev = 1<<(B-1);//(char)(pow(2,B-1)); - - if (qxd <= -maxlev) - qxd = -maxlev; - else if (qxd >= maxlev) - qxd = maxlev-1; - - return((char)qxd); -} - -int main(int argc, char *argv[]) { - time_stats_t timeEncoder,timeDecoder; opp_enabled=1; cpu_freq_GHz = get_cpu_freq_GHz(); diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 3e6222c341..00708ed60c 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -38,7 +38,7 @@ #define MAX_TURBO_ITERATIONS_MBSFN 8 #define MAX_TURBO_ITERATIONS max_turbo_iterations -#define MAX_LDPC_ITERATIONS 5 +#define MAX_LDPC_ITERATIONS 10//5 #define MAX_LDPC_ITERATIONS_MBSFN 4 #define LTE_NULL 2 @@ -454,14 +454,21 @@ int32_t nr_segmentation(unsigned char *input_buffer, unsigned int *C, unsigned int *K, unsigned int *Zout, - unsigned int *F); + unsigned int *F, + uint8_t BG); -uint32_t nr_compute_tbs(uint8_t mcs, - uint16_t nb_rb, - uint16_t nb_symb_sch, - uint8_t nb_re_dmrs, - uint16_t length_dmrs, - uint8_t Nl); +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_oh, + uint8_t Nl); + +uint32_t nr_compute_tbslbrm(uint16_t table, + uint16_t nb_rb, + uint8_t Nl, + uint8_t C); void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f); @@ -474,6 +481,8 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, uint8_t *w, uint8_t *e, uint8_t C, + uint32_t F, + uint32_t Foffset, uint8_t rvidx, uint32_t E); @@ -486,7 +495,9 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, uint8_t C, uint8_t rvidx, uint8_t clear, - uint32_t E); + uint32_t E, + uint32_t F, + uint32_t Foffset); decoder_if_t phy_threegpplte_turbo_decoder; decoder_if_t phy_threegpplte_turbo_decoder8; diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h index 00e8fd98d5..878150a9a8 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_bnProc.h @@ -47,7 +47,7 @@ static inline void nrLDPC_bnProcPc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_proc int8_t* bnProcBufRes = p_procBuf->bnProcBufRes; int8_t* llrRes = p_procBuf->llrRes; int8_t* llrProcBuf = p_procBuf->llrProcBuf; - + __m128i* p_bnProcBuf; __m256i* p_bnProcBufRes; __m128i* p_llrProcBuf; @@ -1693,7 +1693,7 @@ static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBu int8_t* bnProcBuf = p_procBuf->bnProcBuf; int8_t* bnProcBufRes = p_procBuf->bnProcBufRes; int8_t* llrRes = p_procBuf->llrRes; - + __m256i* p_bnProcBuf; __m256i* p_bnProcBufRes; __m256i* p_llrRes; @@ -2775,24 +2775,35 @@ static inline void nrLDPC_llr2bit(int8_t* out, int8_t* llrOut, uint16_t numLLR) } /** - \brief Performs hard-decision on output LLRs and packs the output in 32 bit values. + \brief Performs hard-decision on output LLRs and packs the output in byte aligned output according to TS 38.321 Section 6.1.1. + i = 0,1,2,... + IN[i] : a0, a1, a2, ..., a_{A-1} + OUT[i]: a7,a6,a5,a4,a3,a2,a1,a0|a15,14,...,a8|a23,a22,...,a16|a31,a30,...,a24|... \param out Pointer hard-decision output, every int8_t contains 8 bits \param llrOut Pointer to output LLRs \param numLLR Number of LLRs */ static inline void nrLDPC_llr2bitPacked(int8_t* out, int8_t* llrOut, uint16_t numLLR) { + /** Vector of indices for shuffling input */ + const uint8_t constShuffle_256_epi8[32] __attribute__ ((aligned(32))) = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8}; + __m256i* p_llrOut = (__m256i*) llrOut; uint32_t* p_bits = (uint32_t*) out; + __m256i inPerm; int8_t* p_llrOut8; uint32_t bitsTmp = 0; uint32_t i; uint32_t M = numLLR>>5; uint32_t Mr = numLLR&31; + const __m256i* p_shuffle = (__m256i*) constShuffle_256_epi8; for (i=0; i640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; } - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); @@ -263,8 +241,8 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); // printf("%d\n",no_punctured_columns); // printf("%d\n",removed_bit); // unpack input @@ -273,7 +251,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh if(tinput != NULL) start_meas(tinput); for (i=0; i>(i&7); + c[i] = (test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); } @@ -317,20 +295,18 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh return 0; } -int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) +int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) { - short Zc,Kb=0,nrows=0,ncols=0; - int i,i1,j; + short nrows=0,ncols=0; + int i,i1,j,rate=3; int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; char temp; int simd_size; #ifdef __AVX2__ __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); - __m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats. + __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. __m256i zero256 = _mm256_setzero_si256(); __m256i masks[8]; register __m256i c256; @@ -350,10 +326,9 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i //if (block_length>3840) if (BG==1) { - //BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } //else if (block_length<=3840) else if (BG==2) @@ -361,28 +336,9 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i //BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; - } + rate=5; - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } + } #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); @@ -400,8 +356,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); // printf("%d\n",no_punctured_columns); // printf("%d\n",removed_bit); // unpack input @@ -413,7 +369,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i for (i=0; i>(i&7); + temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); c[i] |= (temp << j); } @@ -431,7 +387,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i for (i=(block_length>>5)<<5;i>(i&7); + temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); c[i] |= (temp << j); } @@ -517,14 +473,13 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i return 0; } -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) +int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) { - short Zc,Kb=0,nrows=0,ncols=0; - int i,i1,j; + short nrows=0,ncols=0; + int i,i1,j,rate=3; int no_punctured_columns,removed_bit; //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; char temp; int simd_size; int macro_segment, macro_segment_end; @@ -537,7 +492,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha #ifdef __AVX2__ __m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000); - __m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats. + __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. __m256i zero256 = _mm256_setzero_si256(); __m256i masks[8]; register __m256i c256; @@ -556,38 +511,16 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha //determine number of bits in codeword if (BG==1) { - BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } else if (BG==2) { - BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; - } - - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; + rate=5; } - } #ifdef DEBUG_LDPC LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); @@ -605,10 +538,10 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + //printf("%d\n",no_punctured_columns); + //printf("%d\n",removed_bit); // unpack input memset(c,0,sizeof(unsigned char) * ncols * Zc); memset(d,0,sizeof(unsigned char) * nrows * Zc); @@ -639,7 +572,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha //for (j=0; j>(i&7); + temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7)); //printf("c(%d,%d)=%d\n",j,i,temp); c[i] |= (temp << (j-macro_segment)); } diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c index 13318c9d5d..5da223dc64 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c @@ -361,24 +361,19 @@ short *choose_generator_matrix(short BG,short Zc) return Gen_shift_values; } -int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length, short BG,unsigned char gen_code) +int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code) { unsigned char c[22*384]; //padded input, unpacked, max size unsigned char d[68*384]; //coded output, unpacked, max size unsigned char channel_temp,temp; short *Gen_shift_values, *no_shift_values, *pointer_shift_values; - short Zc; - //initialize for BG == 1 - short Kb = 22; + short nrows = 46;//parity check bits short ncols = 22;//info bits int i,i1,i2,i3,i4,i5,temp_prime,var; - int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384}; - + int no_punctured_columns,removed_bit,rate=3; int nind=0; int indlist[1000]; int indlist2[1000]; @@ -387,10 +382,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho //if (block_length>3840) if (BG==1) { - //BG=1; - Kb = 22; nrows=46; //parity check bits ncols=22; //info bits + rate=3; } //else if (block_length<=3840) else if (BG==2) @@ -398,33 +392,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho //BG=2; nrows=42; //parity check bits ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; + rate=5; } - //find minimum value in all sets of lifting size - Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } - if (Zc==0) { - printf("ldpc_encoder_orig: could not determine lifting size\n"); - return(-1); - } - Gen_shift_values=choose_generator_matrix(BG,Zc); if (Gen_shift_values==NULL) { printf("ldpc_encoder_orig: could not find generator matrix\n"); @@ -445,11 +415,11 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho pointer_shift_values=(short *) pointer_shift_values_BG2; } else { - AssertFatal(0,"BG %d is not supported yet\n",BG); + AssertFatal(0,"BG %d is not supported yet\n",BG); } - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*3); + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; + removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); //printf("%d\n",no_punctured_columns); //printf("%d\n",removed_bit); // unpack input @@ -460,7 +430,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho { //c[i] = test_input[i/8]<<(i%8); //c[i]=c[i]>>7&1; - c[i]=(test_input[i/8]&(1<<(i&7)))>>(i&7); + c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); } // parity check part diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 66d0fc481c..7ec530242e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -601,7 +601,9 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { uint32_t polar_decoder_int16(int16_t *input, uint64_t *out, - const t_nrPolar_params *polarParams) { + uint8_t ones_flag, + const t_nrPolar_params *polarParams) +{ int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching_int16(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); @@ -645,32 +647,46 @@ uint32_t polar_decoder_int16(int16_t *input, //int len_mod64=len&63; int crclen = polarParams->crcParityBits; uint64_t rxcrc=B[0]&((1<>crclen); - uint8_t A32_flip[4]; + uint8_t A32_flip[4+offset]; + if (ones_flag) { + A32_flip[0] = 0xff; + A32_flip[1] = 0xff; + A32_flip[2] = 0xff; + } uint32_t Aprime= (uint32_t)(Ar<<(32-len)); - A32_flip[0]=((uint8_t *)&Aprime)[3]; - A32_flip[1]=((uint8_t *)&Aprime)[2]; - A32_flip[2]=((uint8_t *)&Aprime)[1]; - A32_flip[3]=((uint8_t *)&Aprime)[0]; - crc = (uint64_t)(crc24c(A32_flip,len)>>8); + A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; + A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; + A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; + A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; + crc = (uint64_t)(crc24c(A32_flip,8*offset+len)>>8); } else if (len<=64) { Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));; - uint8_t A64_flip[8]; - uint64_t Aprime= (uint32_t)(Ar<<(64-len)); - A64_flip[0]=((uint8_t *)&Aprime)[7]; - A64_flip[1]=((uint8_t *)&Aprime)[6]; - A64_flip[2]=((uint8_t *)&Aprime)[5]; - A64_flip[3]=((uint8_t *)&Aprime)[4]; - A64_flip[4]=((uint8_t *)&Aprime)[3]; - A64_flip[5]=((uint8_t *)&Aprime)[2]; - A64_flip[6]=((uint8_t *)&Aprime)[1]; - A64_flip[7]=((uint8_t *)&Aprime)[0]; - crc = (uint64_t)(crc24c(A64_flip,len)>>8); + uint8_t A64_flip[8+offset]; + if (ones_flag) { + A64_flip[0] = 0xff; + A64_flip[1] = 0xff; + A64_flip[2] = 0xff; + } + uint64_t Aprime= (uint64_t)(Ar<<(64-len)); + A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; + A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; + A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; + A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; + A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; + A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; + A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; + A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; + crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8); } #if 0 diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 493b43ee74..6e01a05d0f 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -148,6 +148,7 @@ void polar_encoder_dci(uint32_t *in, void polar_encoder_fast(uint64_t *A, uint32_t *out, int32_t crcmask, + uint8_t ones_flag, t_nrPolar_params *polarParams); int8_t polar_decoder(double *input, @@ -157,6 +158,7 @@ int8_t polar_decoder(double *input, uint32_t polar_decoder_int16(int16_t *input, uint64_t *out, + uint8_t ones_flag, const t_nrPolar_params *polarParams); int8_t polar_decoder_dci(double *input, @@ -185,7 +187,9 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams); t_nrPolar_params *nr_polar_params (int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level); + uint8_t aggregation_level, + int decoder_flag, + t_nrPolar_params **polarList_ext); uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index 9858f16cb0..8e4b45f744 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -268,7 +268,7 @@ static inline void polar_rate_matching(t_nrPolar_params *polarParams,void *in,vo #endif for (int i=0; iencoderLength; i++) { #ifdef DEBUG_POLAR_ENCODER - printf("%u<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]); + printf("%d<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]); #endif tmp0 = (*in128&(((uint128_t)1)<rate_matching_pattern[i])); if (tmp0!=0) { @@ -410,6 +410,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) { void polar_encoder_fast(uint64_t *A, uint32_t *out, int32_t crcmask, + uint8_t ones_flag, t_nrPolar_params *polarParams) { AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); @@ -421,6 +422,10 @@ void polar_encoder_fast(uint64_t *A, AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); //int bitlen0=bitlen; uint64_t tcrc=0; + uint8_t offset = 0; + + // appending 24 ones before a0 for DCI as stated in 38.212 7.3.2 + if (ones_flag) offset = 3; // A bit string should be stored as 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, //???a'_{N-1} a'_{N-2} ... a'_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A @@ -428,38 +433,53 @@ void polar_encoder_fast(uint64_t *A, // First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH) // CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH) if (bitlen<=32) { - uint8_t A32_flip[4]; + uint8_t A32_flip[4+offset]; + if (ones_flag) { + A32_flip[0] = 0xff; + A32_flip[1] = 0xff; + A32_flip[2] = 0xff; + } uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); - A32_flip[0]=((uint8_t *)&Aprime)[3]; - A32_flip[1]=((uint8_t *)&Aprime)[2]; - A32_flip[2]=((uint8_t *)&Aprime)[1]; - A32_flip[3]=((uint8_t *)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8))); + A32_flip[0+offset]=((uint8_t *)&Aprime)[3]; + A32_flip[1+offset]=((uint8_t *)&Aprime)[2]; + A32_flip[2+offset]=((uint8_t *)&Aprime)[1]; + A32_flip[3+offset]=((uint8_t *)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8))); } else if (bitlen<=64) { - uint8_t A64_flip[8]; - uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen)); - A64_flip[0]=((uint8_t *)&Aprime)[7]; - A64_flip[1]=((uint8_t *)&Aprime)[6]; - A64_flip[2]=((uint8_t *)&Aprime)[5]; - A64_flip[3]=((uint8_t *)&Aprime)[4]; - A64_flip[4]=((uint8_t *)&Aprime)[3]; - A64_flip[5]=((uint8_t *)&Aprime)[2]; - A64_flip[6]=((uint8_t *)&Aprime)[1]; - A64_flip[7]=((uint8_t *)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8))); + uint8_t A64_flip[8+offset]; + if (ones_flag) { + A64_flip[0] = 0xff; + A64_flip[1] = 0xff; + A64_flip[2] = 0xff; + } + uint64_t Aprime= (uint64_t)(((uint64_t)*A)<<(64-bitlen)); + A64_flip[0+offset]=((uint8_t *)&Aprime)[7]; + A64_flip[1+offset]=((uint8_t *)&Aprime)[6]; + A64_flip[2+offset]=((uint8_t *)&Aprime)[5]; + A64_flip[3+offset]=((uint8_t *)&Aprime)[4]; + A64_flip[4+offset]=((uint8_t *)&Aprime)[3]; + A64_flip[5+offset]=((uint8_t *)&Aprime)[2]; + A64_flip[6+offset]=((uint8_t *)&Aprime)[1]; + A64_flip[7+offset]=((uint8_t *)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8))); } else if (bitlen<=128) { - uint8_t A128_flip[16]; - uint128_t Aprime= (uint32_t)(((uint128_t)*A)<<(128-bitlen)); - A128_flip[0]=((uint8_t*)&Aprime)[15]; A128_flip[1]=((uint8_t*)&Aprime)[14]; - A128_flip[2]=((uint8_t*)&Aprime)[13]; A128_flip[3]=((uint8_t*)&Aprime)[12]; - A128_flip[4]=((uint8_t*)&Aprime)[11]; A128_flip[5]=((uint8_t*)&Aprime)[10]; - A128_flip[6] =((uint8_t*)&Aprime)[9]; A128_flip[7] =((uint8_t*)&Aprime)[8]; - A128_flip[8] =((uint8_t*)&Aprime)[7]; A128_flip[9] =((uint8_t*)&Aprime)[6]; - A128_flip[10]=((uint8_t*)&Aprime)[5]; A128_flip[11]=((uint8_t*)&Aprime)[4]; - A128_flip[12]=((uint8_t*)&Aprime)[3]; A128_flip[13]=((uint8_t*)&Aprime)[2]; - A128_flip[14]=((uint8_t*)&Aprime)[1]; A128_flip[15]=((uint8_t*)&Aprime)[0]; - tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,bitlen)>>8))); + uint8_t A128_flip[16+offset]; + if (ones_flag) { + A128_flip[0] = 0xff; + A128_flip[1] = 0xff; + A128_flip[2] = 0xff; + } + uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen)); + A128_flip[0+offset]=((uint8_t*)&Aprime)[15]; A128_flip[1+offset]=((uint8_t*)&Aprime)[14]; + A128_flip[2+offset]=((uint8_t*)&Aprime)[13]; A128_flip[3+offset]=((uint8_t*)&Aprime)[12]; + A128_flip[4+offset]=((uint8_t*)&Aprime)[11]; A128_flip[5+offset]=((uint8_t*)&Aprime)[10]; + A128_flip[6+offset] =((uint8_t*)&Aprime)[9]; A128_flip[7+offset] =((uint8_t*)&Aprime)[8]; + A128_flip[8+offset] =((uint8_t*)&Aprime)[7]; A128_flip[9+offset] =((uint8_t*)&Aprime)[6]; + A128_flip[10+offset]=((uint8_t*)&Aprime)[5]; A128_flip[11+offset]=((uint8_t*)&Aprime)[4]; + A128_flip[12+offset]=((uint8_t*)&Aprime)[3]; A128_flip[13+offset]=((uint8_t*)&Aprime)[2]; + A128_flip[14+offset]=((uint8_t*)&Aprime)[1]; A128_flip[15+offset]=((uint8_t*)&Aprime)[0]; + tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8))); } int n; @@ -473,7 +493,6 @@ void polar_encoder_fast(uint64_t *A, //??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0 - for (n=0; ncrcParityBits) | tcrc; else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); diff --git a/openair1/PHY/CODING/nr_compute_tbs.c b/openair1/PHY/CODING/nr_compute_tbs.c deleted file mode 100644 index e1c15d4a86..0000000000 --- a/openair1/PHY/CODING/nr_compute_tbs.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* file: nr_compute_tbs.c - purpose: Compute NR TBS - author: Hongzhi WANG (TCL) -*/ -#include "PHY/defs_nr_UE.h" -//#include "SCHED/extern.h" - -#define INDEX_MAX_TBS_TABLE (93) -//Table 5.1.3.1-1 -uint16_t Mcsindextable1[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, - {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; -//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}; - -uint32_t nr_compute_tbs(uint8_t mcs, - uint16_t nb_rb, - uint16_t nb_symb_sch, - uint8_t nb_re_dmrs, - uint16_t length_dmrs, - uint8_t Nl) -{ - uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh,Qm,R; - uint32_t nr_tbs=0; - double Ninfo,Np_info,n,C; - - nb_rb_oh = 0; //set to 0 if not configured by higher layer - Qm = Mcsindextable1[mcs][0]; - R = Mcsindextable1[mcs][1]; - nb_dmrs_prb = nb_re_dmrs*length_dmrs; - - nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh; - - nb_re = min(156, nbp_re) * nb_rb; - - // Intermediate number of information bits - Ninfo = (double)((nb_re * R * Qm * Nl)/1024); - - //printf("Ninfo %lf nbp_re %d nb_re %d mcs %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re,mcs, Qm, R); - - if (Ninfo <=3824) { - - n = max(3, floor(log2(Ninfo)) - 6); - Np_info = max(24, pow(2,n) * floor(Ninfo/pow(2,n))); - - for (int i=0; i= Np_info){ - nr_tbs = Tbstable_nr[i]; - break; - } - } - } - else { - n = floor(log2(Ninfo-24)) - 5; - Np_info = max(3840, pow(2,n) * round((Ninfo - 24)/pow(2,n))); - - if (R <= 256) { //1/4 - C = ceil( (Np_info + 24)/3816 ); - nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24); - } - else { - if (Np_info > 8424){ - C = ceil( (Np_info + 24)/8424 ); - nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24); - } - else { - nr_tbs = (uint32_t)(8 * ceil( (Np_info + 24)/8 ) - 24); - //printf("n %lf Np_info %f pow %f ceil %f \n",n, Np_info,pow(2,6),ceil( (Np_info + 24)/8 )); - } - - } - - } - - return nr_tbs; -} diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index efc78d91fd..f6a06b3f7f 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -40,7 +40,8 @@ static int intcmp(const void *p1,const void *p2) { static void nr_polar_init(t_nrPolar_params * *polarParams, int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level) { + uint8_t aggregation_level, + int decoder_flag) { t_nrPolar_params *currentPtr = *polarParams; uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level); @@ -150,7 +151,7 @@ static void nr_polar_init(t_nrPolar_params * *polarParams, newPolarInitNode->i_bil, newPolarInitNode->encoderLength); free(J); - build_decoder_tree(newPolarInitNode); + if (decoder_flag == 1) build_decoder_tree(newPolarInitNode); build_polar_tables(newPolarInitNode); init_polar_deinterleaver_table(newPolarInitNode); //printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes); @@ -183,10 +184,13 @@ void nr_polar_print_polarParams(t_nrPolar_params *polarParams) { t_nrPolar_params *nr_polar_params (int8_t messageType, uint16_t messageLength, - uint8_t aggregation_level) { + uint8_t aggregation_level, + int decoding_flag, + t_nrPolar_params **polarList_ext) { static t_nrPolar_params *polarList = NULL; - nr_polar_init(&polarList, messageType,messageLength,aggregation_level); - t_nrPolar_params *polarParams=polarList; + nr_polar_init(polarList_ext != NULL ? polarList_ext : &polarList, + messageType,messageLength,aggregation_level,decoding_flag); + t_nrPolar_params *polarParams=polarList_ext != NULL ? *polarList_ext : polarList; const int tag=messageType * messageLength * nr_polar_aggregation_prime(aggregation_level); while (polarParams != NULL) { diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c index 0954939a58..9691932518 100644 --- a/openair1/PHY/CODING/nr_rate_matching.c +++ b/openair1/PHY/CODING/nr_rate_matching.c @@ -32,23 +32,281 @@ uint8_t index_k0[2][4] = {{0,17,33,56},{0,13,25,43}}; - void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f) { uint32_t EQm; EQm = E/Qm; memset(f,0,E*sizeof(uint8_t)); + uint8_t *e0,*e1,*e2,*e3,*e4,*e5,*e6,*e7; + uint8_t *fp; +#if 0 //def __AVX2__ + __m256i tmp0,tmp1,tmp2,tmp0b,tmp1b,tmp3,tmp4,tmp5; + __m256i *e0_256,*e1_256,*e2_256,*e3_256,*e4_256,*e5_256,*e6_256,*e7_256; - for (int j = 0; j< EQm; j++){ - for (int i = 0; i< Qm; i++){ - f[(i+j*Qm)] = e[(i*EQm + j)]; - } + __m256i *f_256=(__m256i *)f; + + uint8_t *fp2; + switch(Qm) { + case 2: + e0=e; + e1=e0+EQm; + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + for (int k=0,j=0;j>5;j++,k+=2) { + f_256[k] = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); + f_256[k+1] = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); + } + break; + case 4: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + e2_256=(__m256i *)e2; + e3_256=(__m256i *)e3; + for (int k=0,j=0;j>5;j++,k+=4) { + tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15) + tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15) + f_256[k] = _mm256_unpacklo_epi8(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7) + f_256[k+1] = _mm256_unpackhi_epi8(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) + tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31) + tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31) + f_256[k+2] = _mm256_unpacklo_epi8(tmp0,tmp1); + f_256[k+3] = _mm256_unpackhi_epi8(tmp0,tmp1); + } + break; + case 6: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + e2_256=(__m256i *)e2; + e3_256=(__m256i *)e3; + e4_256=(__m256i *)e4; + e5_256=(__m256i *)e5; + + for (int j=0,k=0;j>5;j++,k+=192) { + fp = f+k; + fp2 = fp+96; + + tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15) + tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15) + tmp0b = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7) + tmp1b = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) + tmp0 = _mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15) + *((uint32_t*)fp) = _mm256_extract_epi32(tmp0b,0); + *((uint16_t*)(fp+4)) = _mm256_extract_epi16(tmp0,0); + *((uint32_t*)(fp+6)) = _mm256_extract_epi32(tmp0b,1); + *((uint16_t*)(fp+10)) = _mm256_extract_epi16(tmp0,1); + *((uint32_t*)(fp+12)) = _mm256_extract_epi32(tmp0b,2); + *((uint16_t*)(fp+16)) = _mm256_extract_epi16(tmp0,2); + *((uint32_t*)(fp+18)) = _mm256_extract_epi32(tmp0b,3); + *((uint16_t*)(fp+22)) = _mm256_extract_epi16(tmp0,3); + *((uint32_t*)(fp+24)) = _mm256_extract_epi32(tmp0b,4); + *((uint16_t*)(fp+26)) = _mm256_extract_epi16(tmp0,4); + *((uint32_t*)(fp+30)) = _mm256_extract_epi32(tmp0b,5); + *((uint16_t*)(fp+34)) = _mm256_extract_epi16(tmp0,5); + *((uint32_t*)(fp+36)) = _mm256_extract_epi32(tmp0,6); + *((uint16_t*)(fp+40)) = _mm256_extract_epi16(tmp0,6); + *((uint32_t*)(fp+42)) = _mm256_extract_epi32(tmp0b,7); + *((uint16_t*)(fp+46)) = _mm256_extract_epi16(tmp0,7); + + *((uint32_t*)(fp+48)) = _mm256_extract_epi32(tmp1b,0); + *((uint16_t*)(fp+52)) = _mm256_extract_epi16(tmp0,8); + *((uint32_t*)(fp+56)) = _mm256_extract_epi32(tmp1b,1); + *((uint16_t*)(fp+60)) = _mm256_extract_epi16(tmp0,9); + *((uint32_t*)(fp+62)) = _mm256_extract_epi32(tmp1b,2); + *((uint16_t*)(fp+66)) = _mm256_extract_epi16(tmp0,10); + *((uint32_t*)(fp+68)) = _mm256_extract_epi32(tmp1b,3); + *((uint16_t*)(fp+72)) = _mm256_extract_epi16(tmp0,11); + *((uint32_t*)(fp+74)) = _mm256_extract_epi32(tmp1b,4); + *((uint16_t*)(fp+76)) = _mm256_extract_epi16(tmp0,12); + *((uint32_t*)(fp+80)) = _mm256_extract_epi32(tmp1b,5); + *((uint16_t*)(fp+82)) = _mm256_extract_epi16(tmp0,13); + *((uint32_t*)(fp+86)) = _mm256_extract_epi32(tmp1b,6); + *((uint16_t*)(fp+90)) = _mm256_extract_epi16(tmp0,14); + *((uint32_t*)(fp+92)) = _mm256_extract_epi32(tmp1b,7); + *((uint16_t*)(fp+94)) = _mm256_extract_epi16(tmp0,15); + + tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31) + tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31) + tmp0b = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23) + tmp1b = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31) + tmp0 = _mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31) + *((uint32_t*)fp2) = _mm256_extract_epi32(tmp0b,0); + *((uint16_t*)(fp2+4)) = _mm256_extract_epi16(tmp0,0); + *((uint32_t*)(fp2+6)) = _mm256_extract_epi32(tmp0b,1); + *((uint16_t*)(fp2+10)) = _mm256_extract_epi16(tmp0,1); + *((uint32_t*)(fp2+12)) = _mm256_extract_epi32(tmp0b,2); + *((uint16_t*)(fp2+16)) = _mm256_extract_epi16(tmp0,2); + *((uint32_t*)(fp2+18)) = _mm256_extract_epi32(tmp0b,3); + *((uint16_t*)(fp2+22)) = _mm256_extract_epi16(tmp0,3); + *((uint32_t*)(fp2+24)) = _mm256_extract_epi32(tmp0b,4); + *((uint16_t*)(fp2+26)) = _mm256_extract_epi16(tmp0,4); + *((uint32_t*)(fp2+30)) = _mm256_extract_epi32(tmp0b,5); + *((uint16_t*)(fp2+34)) = _mm256_extract_epi16(tmp0,5); + *((uint32_t*)(fp2+36)) = _mm256_extract_epi32(tmp0,6); + *((uint16_t*)(fp2+40)) = _mm256_extract_epi16(tmp0,6); + *((uint32_t*)(fp2+42)) = _mm256_extract_epi32(tmp0b,7); + *((uint16_t*)(fp2+46)) = _mm256_extract_epi16(tmp0,7); + + *((uint32_t*)(fp2+48)) = _mm256_extract_epi32(tmp1b,0); + *((uint16_t*)(fp2+52)) = _mm256_extract_epi16(tmp0,8); + *((uint32_t*)(fp2+56)) = _mm256_extract_epi32(tmp1b,1); + *((uint16_t*)(fp2+60)) = _mm256_extract_epi16(tmp0,9); + *((uint32_t*)(fp2+62)) = _mm256_extract_epi32(tmp1b,2); + *((uint16_t*)(fp2+66)) = _mm256_extract_epi16(tmp0,10); + *((uint32_t*)(fp2+68)) = _mm256_extract_epi32(tmp1b,3); + *((uint16_t*)(fp2+72)) = _mm256_extract_epi16(tmp0,11); + *((uint32_t*)(fp2+74)) = _mm256_extract_epi32(tmp1b,4); + *((uint16_t*)(fp2+76)) = _mm256_extract_epi16(tmp0,12); + *((uint32_t*)(fp2+80)) = _mm256_extract_epi32(tmp1b,5); + *((uint16_t*)(fp2+82)) = _mm256_extract_epi16(tmp0,13); + *((uint32_t*)(fp2+86)) = _mm256_extract_epi32(tmp1b,6); + *((uint16_t*)(fp2+90)) = _mm256_extract_epi16(tmp0,14); + *((uint32_t*)(fp2+92)) = _mm256_extract_epi32(tmp1b,7); + *((uint16_t*)(fp2+94)) = _mm256_extract_epi16(tmp0,15); + } + break; + case 8: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + e6=e5+EQm; + e7=e6+EQm; + + e0_256=(__m256i *)e0; + e1_256=(__m256i *)e1; + e2_256=(__m256i *)e2; + e3_256=(__m256i *)e3; + e4_256=(__m256i *)e4; + e5_256=(__m256i *)e5; + e6_256=(__m256i *)e6; + e7_256=(__m256i *)e7; + for (int k=0,j=0;j>5;j++,k+=8) { + tmp0 = _mm256_unpacklo_epi8(e0_256[j],e1_256[j]); // e0(i) e1(i) e0(i+1) e1(i+1) .... e0(i+15) e1(i+15) + tmp1 = _mm256_unpacklo_epi8(e2_256[j],e3_256[j]); // e2(i) e3(i) e2(i+1) e3(i+1) .... e2(i+15) e3(i+15) + tmp2 = _mm256_unpacklo_epi8(e4_256[j],e5_256[j]); // e4(i) e5(i) e4(i+1) e5(i+1) .... e4(i+15) e5(i+15) + tmp3 = _mm256_unpacklo_epi8(e6_256[j],e7_256[j]); // e6(i) e7(i) e6(i+1) e7(i+1) .... e6(i+15) e7(i+15) + tmp4 = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i) e1(i) e2(i) e3(i) ... e0(i+7) e1(i+7) e2(i+7) e3(i+7) + tmp5 = _mm256_unpacklo_epi16(tmp2,tmp3); // e4(i) e5(i) e6(i) e7(i) ... e4(i+7) e5(i+7) e6(i+7) e7(i+7) + f_256[k] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i) e1(i) e2(i) e3(i) e4(i) e5(i) e6(i) e7(i)... e0(i+3) e1(i+3) e2(i+3) e3(i+3) e4(i+3) e5(i+3) e6(i+3) e7(i+3)) + f_256[k+1] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+4) e1(i+4) e2(i+4) e3(i+4) e4(i+4) e5(i+4) e6(i+4) e7(i+4)... e0(i+7) e1(i+7) e2(i+7) e3(i+7) e4(i+7) e5(i+7) e6(i+7) e7(i+7)) + + tmp4 = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) ... e0(i+15) e1(i+15) e2(i+15) e3(i+15) + tmp5 = _mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+8) e5(i+8) e6(i+8) e7(i+8) ... e4(i+15) e5(i+15) e6(i+15) e7(i+15) + f_256[k+2] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+8) e1(i+8) e2(i+8) e3(i+8) e4(i+8) e5(i+8) e6(i+8) e7(i+8)... e0(i+11) e1(i+11) e2(i+11) e3(i+11) e4(i+11) e5(i+11) e6(i+11) e7(i+11)) + f_256[k+3] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+12) e1(i+12) e2(i+12) e3(i+12) e4(i+12) e5(i+12) e6(i+12) e7(i+12)... e0(i+15) e1(i+15) e2(i+15) e3(i+15) e4(i+15) e5(i+15) e6(i+15) e7(i+15)) + + tmp0 = _mm256_unpackhi_epi8(e0_256[j],e1_256[j]); // e0(i+16) e1(i+16) e0(i+17) e1(i+17) .... e0(i+31) e1(i+31) + tmp1 = _mm256_unpackhi_epi8(e2_256[j],e3_256[j]); // e2(i+16) e3(i+16) e2(i+17) e3(i+17) .... e2(i+31) e3(i+31) + tmp2 = _mm256_unpackhi_epi8(e4_256[j],e5_256[j]); // e4(i+16) e5(i+16) e4(i+17) e5(i+17) .... e4(i+31) e5(i+31) + tmp3 = _mm256_unpackhi_epi8(e6_256[j],e7_256[j]); // e6(i+16) e7(i+16) e6(i+17) e7(i+17) .... e6(i+31) e7(i+31) + tmp4 = _mm256_unpacklo_epi16(tmp0,tmp1); // e0(i+!6) e1(i+16) e2(i+16) e3(i+16) ... e0(i+23) e1(i+23) e2(i+23) e3(i+23) + tmp5 = _mm256_unpacklo_epi16(tmp2,tmp3); // e4(i+16) e5(i+16) e6(i+16) e7(i+16) ... e4(i+23) e5(i+23) e6(i+23) e7(i+23) + f_256[k+4] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+16) e1(i+16) e2(i+16) e3(i+16) e4(i+16) e5(i+16) e6(i+16) e7(i+16)... e0(i+19) e1(i+19) e2(i+19) e3(i+19) e4(i+19) e5(i+19) e6(i+19) e7(i+19)) + f_256[k+5] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+20) e1(i+20) e2(i+20) e3(i+20) e4(i+20) e5(i+20) e6(i+20) e7(i+20)... e0(i+23) e1(i+23) e2(i+23) e3(i+23) e4(i+23) e5(i+23) e6(i+23) e7(i+23)) + + tmp4 = _mm256_unpackhi_epi16(tmp0,tmp1); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) ... e0(i+31) e1(i+31) e2(i+31) e3(i+31) + tmp5 = _mm256_unpackhi_epi16(tmp2,tmp3); // e4(i+24) e5(i+24) e6(i+24) e7(i+24) ... e4(i+31) e5(i+31) e6(i+31) e7(i+31) + f_256[k+6] = _mm256_unpacklo_epi16(tmp4,tmp5); // e0(i+24) e1(i+24) e2(i+24) e3(i+24) e4(i+24) e5(i+24) e6(i+24) e7(i+24)... e0(i+27) e1(i+27) e2(i+27) e3(i+27) e4(i+27) e5(i+27) e6(i+27) e7(i+27)) + f_256[k+7] = _mm256_unpackhi_epi16(tmp4,tmp5); // e0(i+28) e1(i+28) e2(i+28) e3(i+28) e4(i+28) e5(i+28) e6(i+28) e7(i+28)... e0(i+31) e1(i+31) e2(i+31) e3(i+31) e4(i+31) e5(i+31) e6(i+31) e7(i+31)) + } + break; + default: AssertFatal(1==0,"Should be here!\n"); } +#else + //original unoptimized loops + /* + for (int j = 0; j< EQm; j++,j2+=2){ + for (int i = 0; i< Qm; i++){ + f[(i+j*Qm)] = e[(i*EQm + j)]; + } + } + */ + + int j2=0; + fp=f; + switch (Qm) { + case 2: + e0=e; + e1=e0+EQm; + for (int j = 0; j< EQm; j++,j2+=2){ + fp=&f[j2]; + fp[0] = e0[j]; + fp[1] = e1[j]; + } + break; + case 4: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + for (int j = 0; j< EQm; j++,j2+=4){ + fp=&f[j2]; + fp[0] = e0[j]; + fp[1] = e1[j]; + fp[2] = e2[j]; + fp[3] = e3[j]; + } + break; + case 6: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + fp = f; + for (int j = 0; j< EQm; j++){ + *fp++ = e0[j]; + *fp++ = e1[j]; + *fp++ = e2[j]; + *fp++ = e3[j]; + *fp++ = e4[j]; + *fp++ = e5[j]; + } + break; + case 8: + e0=e; + e1=e0+EQm; + e2=e1+EQm; + e3=e2+EQm; + e4=e3+EQm; + e5=e4+EQm; + e6=e5+EQm; + e7=e6+EQm; + for (int j = 0; j< EQm; j++,j2+=8){ + fp=&f[j2]; + fp[0] = e0[j]; + fp[1] = e1[j]; + fp[2] = e2[j]; + fp[3] = e3[j]; + fp[4] = e4[j]; + fp[5] = e5[j]; + fp[6] = e6[j]; + fp[7] = e7[j]; + } + break; + default: AssertFatal(1==0,"Should never be here!\n"); + } +#endif } + + void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f) { @@ -71,6 +329,8 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, uint8_t *w, uint8_t *e, uint8_t C, + uint32_t F, + uint32_t Foffset, uint8_t rvidx, uint32_t E) { @@ -94,21 +354,36 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z; #ifdef RM_DEBUG - printf("nr_rate_matching_ldpc: E %d, k0 %d, Ncb %d, rvidx %d\n", E, ind, Ncb, rvidx); + printf("nr_rate_matching_ldpc: E %d, F %d, Foffset %d, k0 %d, Ncb %d, rvidx %d\n", E, F, Foffset,ind, Ncb, rvidx); #endif + AssertFatal(Foffset <= E,"Foffset %d > E %d\n",Foffset,E); + AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb); - k=0; + if (ind >= Foffset && ind < (F+Foffset)) ind = F+Foffset; - for (; (ind E %d\n",Foffset,E); + AssertFatal(Foffset <= Ncb,"Foffset %d > Ncb %d\n",Foffset,Ncb); #ifdef RM_DEBUG printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, k0 %d, Ncb %d, rvidx %d\n", clear, E, ind, Ncb, rvidx); #endif - if (clear==1) - memset(w,0,Ncb*sizeof(int16_t)); + if (clear==1) memset(w,0,Ncb*sizeof(int16_t)); k=0; + if (ind < Foffset) + for (; (ind",k,ind,w[ind],soft_input[k]); +#endif + w[ind]+=soft_input[k++]; +#ifdef RM_DEBUG + printf("%d\n",w[ind]); +#endif + } + if (ind >= Foffset && ind < Foffset+F) ind=Foffset+F; + for (; (ind",k,ind,w[ind],soft_input[k]); +#endif w[ind] += soft_input[k++]; #ifdef RM_DEBUG - printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]); -#endif - } - -#ifdef RM_DEBUG - else { - printf("RM_RX Ind: %d NULL %d\n",ind,nulled); - nulled++; - } - + printf("%d\n",w[ind]); #endif } - if (rvidx !=0){ while(k",k,ind,w[ind],soft_input[k]); #endif - } - + w[ind]+=soft_input[k++]; #ifdef RM_DEBUG - else { - printf("RM_RX Ind: %d NULL %d\n",ind,nulled); - nulled++; - } - + printf("%d\n",w[ind]); +#endif + } + for (ind=Foffset+F; (ind",k,ind,w[ind],soft_input[k]); +#endif + w[ind] += soft_input[k++]; +#ifdef RM_DEBUG + printf("%d\n",w[ind]); #endif } } - } + return 0; } + diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c index 421f440ec2..462cdee1fc 100644 --- a/openair1/PHY/CODING/nr_segmentation.c +++ b/openair1/PHY/CODING/nr_segmentation.c @@ -35,55 +35,65 @@ int32_t nr_segmentation(unsigned char *input_buffer, unsigned int *C, unsigned int *K, unsigned int *Zout, // [hna] Zout is Zc - unsigned int *F) + unsigned int *F, + uint8_t BG) { - unsigned int L,Bprime,Bprime_by_C,Z,r,Kb,k,s,crc,Kprime; + unsigned int L,Bprime,Z,r,Kcb,Kb,k,s,crc,Kprime; - if (B<=8448) { + if (BG==1) + Kcb=8448; + else + Kcb=3840; + + if (B<=Kcb) { L=0; *C=1; Bprime=B; } else { L=24; - *C = B/(8448-L); + *C = B/(Kcb-L); - if ((8448-L)*(*C) < B) + if ((Kcb-L)*(*C) < B) *C=*C+1; Bprime = B+((*C)*L); #ifdef DEBUG_SEGMENTATION - printf("Bprime %d\n",Bprime); + printf("Bprime %u\n",Bprime); #endif } - if ((*C)>MAX_NUM_DLSCH_SEGMENTS) { - LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime); + if ((*C)>MAX_NUM_NR_DLSCH_SEGMENTS) { + LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime); return(-1); } // Find K+ - Bprime_by_C = Bprime/(*C); - if (Bprime <=192) { - Kb = 6; - } else if (Bprime <=560) { - Kb = 8; - } else if (Bprime <=640) { - Kb = 9; - } else if (Bprime <=3840) { - Kb = 10;; - } else { - Kb = 22; + Kprime = Bprime/(*C); + + if (BG==1) + Kb = 22; + else { + if (B > 640) { + Kb = 10; + } else if (B > 560) { + Kb = 9; + } else if (B > 192) { + Kb = 8; + } + else { + Kb = 6; + } } -if ((Bprime_by_C%Kb) > 0) - Z = (Bprime_by_C/Kb)+1; +if ((Kprime%Kb) > 0) + Z = (Kprime/Kb)+1; else - Z = (Bprime_by_C/Kb); + Z = (Kprime/Kb); #ifdef DEBUG_SEGMENTATION - printf("nr segmetation B %d Bprime %d Bprime_by_C %d z %d \n", B, Bprime, Bprime_by_C, Z); + printf("nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z); #endif if (Z <= 2) { @@ -110,7 +120,7 @@ else *K = *K + 8; #ifdef DEBUG_SEGMENTATION - printf("Z_by_C %d , K2 %d\n",Z,*K); + printf("Z_by_C %u , K2 %u\n",Z,*K); #endif } else if (Z <= 256) { // increase by 4 bytes til here *K = (Z>>4)<<4; @@ -128,14 +138,19 @@ else //msg("nr_segmentation.c: Illegal codeword size !!!\n"); return -1; } - *Zout = *K; - *K = *K*Kb; - *F = ((*K) - Bprime_by_C); + *Zout = *K; + + if(BG==1) + *K = *K*22; + else + *K = *K*10; + + *F = ((*K) - Kprime); #ifdef DEBUG_SEGMENTATION - printf("final nr seg output Z %d K %d F %d \n", *Zout, *K, *F); - printf("C %d, K %d, Bprime_bytes %d, Bprime %d, F %d\n",*C,*K,Bprime>>3,Bprime,*F); + printf("final nr seg output Z %u K %u F %u \n", *Zout, *K, *F); + printf("C %u, K %u, Bprime_bytes %u, Bprime %u, F %u\n",*C,*K,Bprime>>3,Bprime,*F); #endif if ((input_buffer) && (output_buffers)) { @@ -145,7 +160,6 @@ else for (r=0; r<*C; r++) { k = 0; - Kprime = Bprime_by_C; while (k<((Kprime - L)>>3)) { output_buffers[r][k] = input_buffer[s]; @@ -154,6 +168,13 @@ else s++; } + if (*C > 1) { // add CRC + crc = crc24b(output_buffers[r],Kprime-L)>>8; + output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2]; + output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1]; + output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0]; + } + if (*F>0) { for (k=Kprime>>3; k<(*K)>>3; k++) { output_buffers[r][k] = 0; @@ -161,16 +182,10 @@ else } } - if (*C > 1) { // add CRC - crc = crc24b(output_buffers[r],Kprime-L)>>8; - output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2]; - output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1]; - output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0]; - } } } - return 0; + return Kb; } diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index d5b5065c9b..2c84af188e 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "executables/nr-softmodem-common.h" #include "PHY/defs_gNB.h" #include "PHY/phy_extern.h" #include "PHY/NR_REFSIG/nr_refsig.h" @@ -30,7 +31,7 @@ #include "TDD-Config.h" #include "MBSFN-SubframeConfigList.h"*/ #include "openair1/PHY/defs_RU.h" -#include "LAYER2/MAC/mac_extern.h" +#include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "assertions.h" #include @@ -38,6 +39,7 @@ #include "PHY/NR_REFSIG/nr_refsig.h" #include "SCHED_NR/fapi_nr_l1.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "nfapi_nr_interface.h" /* extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); @@ -76,7 +78,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char abstraction_flag) { // shortcuts NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; NR_gNB_PRACH *const prach_vars = &gNB->prach_vars; NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars; @@ -84,12 +86,12 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ int i; + int Ptx=cfg->carrier_config.num_tx_ant.value; + int Prx=cfg->carrier_config.num_rx_ant.value; + AssertFatal(Ptx>0 && Ptx<9,"Ptx %d is not supported\n",Ptx); + AssertFatal(Prx>0 && Prx<9,"Prx %d is not supported\n",Prx); LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__); - gNB->total_dlsch_bitrate = 0; - gNB->total_transmitted_bits = 0; - gNB->total_system_throughput = 0; - gNB->check_for_MUMIMO_transmissions=0; while(gNB->configured == 0) usleep(10000); @@ -127,7 +129,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } } - nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); + nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value); nr_init_pbch_interleaver(gNB->nr_pbch_interleaver); //PDSCH DMRS init gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); @@ -148,26 +150,29 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } } - nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); + nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value); /// Transport init necessary for NR synchro init_nr_transport(gNB); - gNB->first_run_I0_measurements = - 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. - common_vars->rxdata = (int32_t **)malloc16(15*sizeof(int32_t*)); - common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); - common_vars->rxdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); + gNB->first_run_I0_measurements = 1; - for (i=0;i<15;i++){ + common_vars->rxdata = (int32_t **)malloc16(Prx*sizeof(int32_t*)); + common_vars->txdataF = (int32_t **)malloc16(Ptx*sizeof(int32_t*)); + common_vars->rxdataF = (int32_t **)malloc16(Prx*sizeof(int32_t*)); + + for (i=0;itxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP - common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); - common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); - LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", - i,common_vars->txdataF[i], - fp->samples_per_frame_wCP*sizeof(int32_t)); + i,common_vars->txdataF[i], + fp->samples_per_frame_wCP*sizeof(int32_t)); + } + for (i=0;irxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); + common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)); + } + // Channel estimates for SRS /* @@ -196,95 +201,61 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, prach_vars->rxsigF = (int16_t *)malloc16_clear( 1024*2*sizeof(int16_t) ); prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t)); + int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; - for (int ulsch_id=0; ulsch_iddlsch[0][0]->harq_processes[0]); + for (int ULSCH_id=0; ULSCH_iddlsch[0][0]->harq_processes[0]); + pusch_vars[ULSCH_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) ); + pusch_vars[ULSCH_id]->rxdataF_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->rxdataF_ext2 = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_estimates = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_estimates_time = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(Prx*sizeof(int32_t *) ); + pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) ); - //FIXME - pusch_vars[ulsch_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) ); - pusch_vars[ulsch_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - pusch_vars[ulsch_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) ); - - for (i=0; i<2; i++) { - // RK 2 times because of output format of FFT! - // FIXME We should get rid of this - pusch_vars[ulsch_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); - pusch_vars[ulsch_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot ); - pusch_vars[ulsch_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); - pusch_vars[ulsch_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 ); + printf("ULSCH_id %d (before rx antenna alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]); + for (i=0; irxdataF_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_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]->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 ); + pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 ); + pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) ); } - - pusch_vars[ulsch_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear + printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]); + pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear + printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]); } //ulsch_id /* for (ulsch_id=0; ulsch_idUE_stats_ptr[ulsch_id] = &gNB->UE_stats[ulsch_id]; */ - gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration + printf("After ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]); return (0); } -/* -void phy_config_request(PHY_Config_t *phy_config) { - - uint8_t Mod_id = phy_config->Mod_id; - int CC_id = phy_config->CC_id; - nfapi_nr_config_request_t *cfg = phy_config->cfg; - - NR_DL_FRAME_PARMS *fp; - PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two}; - int eutra_band = cfg->nfapi_config.rf_bands.rf_band[0]; - int dl_Bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; - int ul_Bandwidth = cfg->rf_config.ul_carrier_bandwidth.value; - int Nid_cell = cfg->sch_config.physical_cell_id.value; - int Ncp = cfg->subframe_config.dl_cyclic_prefix_type.value; - int p_eNB = cfg->rf_config.tx_antenna_ports.value; - uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value; - - LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,gNB_tx_antenna_ports %d,Ncp %d,DL freq %u)\n", - Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq ); - - AssertFatal(RC.gNB != NULL, "PHY instance pointer doesn't exist\n"); - AssertFatal(RC.gNB[Mod_id] != NULL, "PHY instance %d doesn't exist\n",Mod_id); - AssertFatal(RC.gNB[Mod_id][CC_id] != NULL, "PHY instance %d, CCid %d doesn't exist\n",Mod_id,CC_id); - - - if (RC.gNB[Mod_id][CC_id]->configured == 1) - { - LOG_E(PHY,"Already eNB already configured, do nothing\n"); - return; - } - - RC.gNB[Mod_id][CC_id]->mac_enabled = 1; - - fp = &RC.gNB[Mod_id][CC_id]->frame_parms; - - fp->threequarter_fs = 0; - - nr_init_frame_parms(fp,1); - - RC.gNB[Mod_id][CC_id]->configured = 1; - LOG_I(PHY,"gNB %d/%d configured\n",Mod_id,CC_id); -}*/ - void phy_free_nr_gNB(PHY_VARS_gNB *gNB) { //NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms; - //nfapi_nr_config_request_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; - //NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars; + NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars; /*LTE_eNB_SRS *const srs_vars = gNB->srs_vars; LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; + int Ptx=gNB->gNB_config.carrier_config.num_tx_ant.value; - for (int i = 0; i < 15; i++) { + for (int i = 0; i < Ptx; i++) { free_and_zero(common_vars->txdataF[i]); /* rxdataF[i] is not allocated -> don't free */ } @@ -315,29 +286,38 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(prach_vars->prach_ifft[0]); free_and_zero(prach_vars->rxsigF[0]); - - for (UE_id=0; UE_idrxdataF_ext[i]); - free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates[i]); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time[i]); - free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]); - free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]); - free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]); +*/ + for (int ULSCH_id=0; ULSCH_idrxdataF_ext[i]); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag[i]); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb[i]); + free_and_zero(pusch_vars[ULSCH_id]->rho[i]); } - free_and_zero(pusch_vars[UE_id]->rxdataF_ext); - free_and_zero(pusch_vars[UE_id]->rxdataF_ext2); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates); - free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time); - free_and_zero(pusch_vars[UE_id]->rxdataF_comp); - free_and_zero(pusch_vars[UE_id]->ul_ch_mag); - free_and_zero(pusch_vars[UE_id]->ul_ch_magb); - free_and_zero(pusch_vars[UE_id]->llr); - free_and_zero(pusch_vars[UE_id]); - } //UE_id + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_ext2); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_ext); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time); + free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag); + free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb); + free_and_zero(pusch_vars[ULSCH_id]->rho); + free_and_zero(pusch_vars[ULSCH_id]->llr); + free_and_zero(pusch_vars[ULSCH_id]); + } //ULSCH_id +/* for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL; */ } @@ -359,25 +339,28 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, uint64_t position_in_burst) { NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - nfapi_nr_config_request_t *gNB_config = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config; //overwrite for new NR parameters - gNB_config->nfapi_config.rf_bands.rf_band[0] = 78; - gNB_config->nfapi_config.nrarfcn.value = 620000; - gNB_config->subframe_config.numerology_index_mu.value = mu; - gNB_config->subframe_config.duplex_mode.value = TDD; - gNB_config->rf_config.dl_carrier_bandwidth.value = N_RB_DL; - gNB_config->rf_config.ul_carrier_bandwidth.value = N_RB_UL; - gNB_config->sch_config.half_frame_index.value = 0; - gNB_config->sch_config.ssb_subcarrier_offset.value = 0; - gNB_config->sch_config.n_ssb_crb.value = (N_RB_DL-20); - gNB_config->sch_config.ssb_subcarrier_offset.value = 0; - gNB_config->sch_config.physical_cell_id.value = Nid_cell; - gNB_config->sch_config.ssb_scg_position_in_burst.value = position_in_burst; - gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; + + gNB_config->cell_config.phy_cell_id.value = Nid_cell; + gNB_config->ssb_config.scs_common.value = mu; + gNB_config->ssb_table.ssb_subcarrier_offset.value = 0; + gNB_config->ssb_table.ssb_offset_point_a.value = (N_RB_DL-20)>>1; + gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = position_in_burst; + gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = position_in_burst>>32; + gNB_config->cell_config.frame_duplex_type.value = TDD; + gNB_config->ssb_table.ssb_period.value = 1; //10ms + gNB_config->carrier_config.dl_grid_size[mu].value = N_RB_DL; + gNB_config->carrier_config.ul_grid_size[mu].value = N_RB_UL; + gNB_config->carrier_config.num_tx_ant.value = fp->nb_antennas_tx; + gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx; + + //gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; gNB->mac_enabled = 1; fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); + fp->eutra_band = 78; fp->threequarter_fs= 0; nr_init_frame_parms(gNB_config, fp); gNB->configured = 1; @@ -386,42 +369,59 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, void nr_phy_config_request(NR_PHY_Config_t *phy_config) { - uint8_t Mod_id = phy_config->Mod_id; - NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; - nfapi_nr_config_request_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; - gNB_config->nfapi_config.rf_bands.rf_band[0] = phy_config->cfg->nfapi_config.rf_bands.rf_band[0]; //22 - gNB_config->nfapi_config.nrarfcn.value = phy_config->cfg->nfapi_config.nrarfcn.value; //6600 - gNB_config->subframe_config.numerology_index_mu.value = phy_config->cfg->subframe_config.numerology_index_mu.value;//1 - gNB_config->rf_config.dl_carrier_bandwidth.value = phy_config->cfg->rf_config.dl_carrier_bandwidth.value;//106; - gNB_config->rf_config.ul_carrier_bandwidth.value = phy_config->cfg->rf_config.ul_carrier_bandwidth.value;//106; - gNB_config->sch_config.half_frame_index.value = 0; - gNB_config->sch_config.ssb_subcarrier_offset.value = phy_config->cfg->sch_config.ssb_subcarrier_offset.value;//0; - gNB_config->sch_config.n_ssb_crb.value = (phy_config->cfg->rf_config.dl_carrier_bandwidth.value-20); - gNB_config->sch_config.physical_cell_id.value = phy_config->cfg->sch_config.physical_cell_id.value; - gNB_config->sch_config.ssb_scg_position_in_burst.value= phy_config->cfg->sch_config.ssb_scg_position_in_burst.value; - gNB_config->sch_config.ssb_periodicity.value = phy_config->cfg->sch_config.ssb_periodicity.value; + uint8_t Mod_id = phy_config->Mod_id; + NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; + nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; - if (phy_config->cfg->subframe_config.duplex_mode.value == 0) { - gNB_config->subframe_config.duplex_mode.value = TDD; - } else { - gNB_config->subframe_config.duplex_mode.value = FDD; + /* + gNB_config->cell_config.phy_cell_id.value = phy_config->cfg->cell_config.phy_cell_id.value; + gNB_config->carrier_config.dl_frequency.value = phy_config->cfg->carrier_config.dl_frequency.value; + gNB_config->carrier_config.uplink_frequency.value = phy_config->cfg->carrier_config.uplink_frequency.value; + gNB_config->ssb_config.scs_common.value = phy_config->cfg->ssb_config.scs_common.value; + gNB_config->carrier_config.dl_bandwidth.value = phy_config->cfg->carrier_config.dl_bandwidth.value; + gNB_config->carrier_config.uplink_bandwidth.value = phy_config->cfg->carrier_config.uplink_bandwidth.value; + gNB_config->ssb_table.ssb_subcarrier_offset.value = phy_config->cfg->ssb_table.ssb_subcarrier_offset.value; + gNB_config->ssb_table.ssb_offset_point_a.value = phy_config->cfg->ssb_table.ssb_offset_point_a.value; + gNB_config->ssb_table.ssb_mask_list[0].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[0].ssb_mask.value; + gNB_config->ssb_table.ssb_mask_list[1].ssb_mask.value = phy_config->cfg->ssb_table.ssb_mask_list[1].ssb_mask.value; + gNB_config->ssb_table.ssb_period.value = phy_config->cfg->ssb_table.ssb_period.value; + for (int i=0; i<5; i++) { + gNB_config->carrier_config.dl_grid_size[i].value = phy_config->cfg->carrier_config.dl_grid_size[i].value; + gNB_config->carrier_config.ul_grid_size[i].value = phy_config->cfg->carrier_config.ul_grid_size[i].value; + gNB_config->carrier_config.dl_k0[i].value = phy_config->cfg->carrier_config.dl_k0[i].value; + gNB_config->carrier_config.ul_k0[i].value = phy_config->cfg->carrier_config.ul_k0[i].value; } - memcpy((void*)&gNB_config->rach_config,(void*)&phy_config->cfg->rach_config,sizeof(phy_config->cfg->rach_config)); + if (phy_config->cfg->cell_config.frame_duplex_type.value == 0) { + gNB_config->cell_config.frame_duplex_type.value = FDD; + } else { + gNB_config->cell_config.frame_duplex_type.value = TDD; + } + + memcpy((void*)&gNB_config->prach_config,(void*)&phy_config->cfg->prach_config,sizeof(phy_config->cfg->prach_config)); + memcpy((void*)&gNB_config->tdd_table,(void*)&phy_config->cfg->tdd_table,sizeof(phy_config->cfg->tdd_table)); + */ + memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg)); RC.gNB[Mod_id]->mac_enabled = 1; - fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); - fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_nr_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); - LOG_I(PHY,"Configuring MIB for instance %d, : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u)\n", - Mod_id, - gNB_config->nfapi_config.rf_bands.rf_band[0], - gNB_config->rf_config.dl_carrier_bandwidth.value, - gNB_config->rf_config.ul_carrier_bandwidth.value, - gNB_config->sch_config.physical_cell_id.value, - fp->dl_CarrierFreq ); + fp->dl_CarrierFreq = (gNB_config->carrier_config.dl_frequency.value)*1e3 + (gNB_config->carrier_config.dl_bandwidth.value)*5e5; + int32_t dlul_offset = 0; + lte_frame_type_t frame_type = 0; + + get_band(fp->dl_CarrierFreq,&fp->eutra_band,&dlul_offset,&frame_type); + + fp->ul_CarrierFreq = (gNB_config->carrier_config.uplink_frequency.value)*1e3 + (gNB_config->carrier_config.uplink_bandwidth.value)*5e5; + + fp->threequarter_fs = openair0_cfg[0].threequarter_fs; + LOG_I(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n", + Mod_id, + gNB_config->cell_config.phy_cell_id.value, + (unsigned long long)fp->dl_CarrierFreq, + (unsigned long long)fp->ul_CarrierFreq); nr_init_frame_parms(gNB_config, fp); + if (RC.gNB[Mod_id]->configured == 1) { LOG_E(PHY,"Already gNB already configured, do nothing\n"); @@ -436,60 +436,61 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { int i; int j; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; LOG_I(PHY, "Initialise nr transport\n"); + uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value; for (i=0; idlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg); - - if (!gNB->dlsch[i][j]) { - LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i); - exit(-1); - }/* else { - gNB->dlsch[i][j]->rnti=0; - LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti); - }*/ + gNB->dlsch[i][j] = new_gNB_dlsch(fp,1,16,NSOFT,0,grid_size); + AssertFatal(gNB->dlsch[i][j]!=NULL,"Can't initialize dlsch %d \n", i); } } - for (i=0; iulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); - - if (!gNB->ulsch[i][j]) { - LOG_E(PHY,"Can't get gNB ulsch structures\n"); - exit(-1); - } - } - // ULSCH for data - gNB->ulsch[i+1][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); + gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); - if (!gNB->ulsch[i+1][j]) { + if (!gNB->ulsch[i][j]) { LOG_E(PHY,"Can't get gNB ulsch structures\n"); exit(-1); } - ////////////////////////////////////////////////////////////////////////// + + /* + LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i); + // [hna] added here for RT implementation + uint8_t harq_pid = 0; + nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[i+1][j]->harq_processes[harq_pid]->ulsch_pdu; + + // --------- setting rel15_ul parameters ---------- + rel15_ul->rnti = 0x1234; + rel15_ul->ulsch_pdu_rel15.start_rb = 0; + rel15_ul->ulsch_pdu_rel15.number_rbs = 50; + rel15_ul->ulsch_pdu_rel15.start_symbol = 2; + rel15_ul->ulsch_pdu_rel15.number_symbols = 12; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; + rel15_ul->ulsch_pdu_rel15.Qm = 2; + rel15_ul->ulsch_pdu_rel15.R = 679; + rel15_ul->ulsch_pdu_rel15.mcs = 9; + rel15_ul->ulsch_pdu_rel15.rv = 0; + rel15_ul->ulsch_pdu_rel15.n_layers = 1; + /////////////////////////////////////////////////// + */ + } - // this is the transmission mode for the signalling channels - // this will be overwritten with the real transmission mode by the RRC once the UE is connected - //gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2; } gNB->rx_total_gain_dB=130; - for(i=0; imu_mimo_mode[i].dl_pow_off = 2; //fp->pucch_config_common.deltaPUCCH_Shift = 1; } diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 73305e3586..2dcf035866 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -41,6 +41,13 @@ int nr_phy_init_RU(RU_t *ru) { LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); + nfapi_nr_config_request_scf_t *cfg; + ru->nb_log_antennas=0; + for (int n=0;ngNB_config; + if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value; + } + AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas); if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals // Time-domain signals ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*)); @@ -74,6 +81,10 @@ int nr_phy_init_RU(RU_t *ru) { } + // allocate precoding input buffers (TX) + ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); + for(i=0; i< ru->nb_tx; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP + // allocate IFFT input buffers (TX) ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF, @@ -104,37 +115,33 @@ int nr_phy_init_RU(RU_t *ru) { RC.nb_nr_L1_inst,NUMBER_OF_gNB_MAX); LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst); - - for (i=0; ibeam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); - for (j=0; jnb_tx; j++) { - ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); - // antenna ports 0-3 are mapped on antennas 0-3 - // antenna port 4 is mapped on antenna 0 - // antenna ports 5-14 are mapped on all antennas - if (((p<4) && (p==j)) || ((p==4) && (j==0))) { - for (re=0; reofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff; - - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - else if (p>4) { - for (re=0; reofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); - } // for (j=0 - } // if (pnb_log_antennas>1) { + for (p=0;pnb_log_antennas;p++) { + if ((fp->L_ssb >> p) & 0x01) + beam_count++; + } + AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); + + int l_ind = 0; + for (i=0; inb_log_antennas;p++) { + if ((fp->L_ssb >> p) & 0x01) { + ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); + for (j=0; jnb_tx; j++) { + ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); + for (re=0; reofdm_symbol_size; re++) + ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind]; + //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j); + l_ind++; + } // for j + } // for p + } + } //for i + } } // !=IF5 + ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP ); return(0); @@ -161,6 +168,10 @@ void nr_phy_free_RU(RU_t *ru) for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]); free_and_zero(ru->common.rxdata_7_5kHz); + // free beamforming input buffers (TX) + for (i = 0; i < 15; i++) free_and_zero(ru->common.txdataF[i]); + free_and_zero(ru->common.txdataF); + // free IFFT input buffers (TX) for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]); free_and_zero(ru->common.txdataF_BF); @@ -175,10 +186,8 @@ void nr_phy_free_RU(RU_t *ru) for (i = 0; i < RC.nb_nr_L1_inst; i++) { for (p = 0; p < 15; p++) { - if (p == 0 || p == 5) { for (j=0; jnb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); free_and_zero(ru->beam_weights[i][p]); - } } } } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index cd0620012f..2a5df46895 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -649,7 +649,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int i,j,k,l,slot,symb,q; int eNB_id; int th_id; - int n_ssb_crb=(fp->N_RB_DL-20); + int n_ssb_crb=(fp->N_RB_DL-20)>>1; int k_ssb=0; uint32_t ****pusch_dmrs; uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig @@ -877,6 +877,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, pbch_vars[eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pbch_vars[eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pbch_vars[eNB_id]->llr = (int16_t *)malloc16_clear( 1920 ); // prach_vars[eNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); prach_vars[eNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); @@ -888,6 +889,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int idx = (j<<1)+i; pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); pbch_vars[eNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); + pbch_vars[eNB_id]->dl_ch_estimates_time[idx]= (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) ); pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); } } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 00b2b6a7da..a08abf416a 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -27,10 +27,11 @@ uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 16, 32}; -int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index) +int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb) { int mu = fp->numerology_index; + uint8_t half_frame_index = fp->half_frame_bit; int symbol = 0; uint8_t n, n_temp; nr_ssb_type_e type = fp->ssb_type; @@ -79,14 +80,17 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_f return symbol; } - int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, - int mu, + nfapi_nr_config_request_scf_t* cfg, + int mu0, int Ncp, - int N_RB_DL) + int N_RB_DL, + int N_RB_UL) { + int mu = cfg!= NULL ? cfg->ssb_config.scs_common.value : mu0; + #if DISABLE_LOG_X printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp); #else @@ -96,9 +100,11 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, if (Ncp == NFAPI_CP_EXTENDED) AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu); + fp->half_frame_bit = 0; // half frame bit initialized to 0 here fp->numerology_index = mu; fp->Ncp = Ncp; fp->N_RB_DL = N_RB_DL; + fp->N_RB_UL = N_RB_UL; switch(mu) { @@ -224,6 +230,8 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->slots_per_frame = 10* fp->slots_per_subframe; fp->nb_antenna_ports_eNB = 1; // default value until overwritten by RRCConnectionReconfiguration + fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration + fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; @@ -231,35 +239,43 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) + - (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1))); + (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1))); fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; // definition of Lmax according to ts 38.213 section 4.1 - if (fp->dl_CarrierFreq < 6e9){ - if(fp->frame_type && (fp->ssb_type==2)) - fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8; - else - fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8; - } - else + if (fp->dl_CarrierFreq < 6e9) { + if(fp->frame_type && (fp->ssb_type==2)) + fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8; + else + fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8; + } else { fp->Lmax = 64; + } + fp->N_ssb = 0; + int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value; + + for (int p=0; pN_ssb += ((fp->L_ssb >> p) & 0x01); return 0; } -int nr_init_frame_parms(nfapi_nr_config_request_t* config, +int nr_init_frame_parms(nfapi_nr_config_request_scf_t* config, NR_DL_FRAME_PARMS *fp) { - fp->eutra_band = config->nfapi_config.rf_bands.rf_band[0]; - fp->frame_type = !(config->subframe_config.duplex_mode.value); - fp->L_ssb = config->sch_config.ssb_scg_position_in_burst.value; + fp->frame_type = config->cell_config.frame_duplex_type.value; + fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask.value)<<32) | config->ssb_table.ssb_mask_list[0].ssb_mask.value ; + int N_RB_DL = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; + int N_RB_UL = config->carrier_config.ul_grid_size[config->ssb_config.scs_common.value].value; return nr_init_frame_parms0(fp, - config->subframe_config.numerology_index_mu.value, - config->subframe_config.dl_cyclic_prefix_type.value, - config->rf_config.dl_carrier_bandwidth.value); + config, + 0, + NFAPI_CP_NORMAL, + N_RB_DL, + N_RB_UL); } int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, @@ -269,9 +285,9 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, int n_ssb_crb, int ssb_subcarrier_offset) { - /*n_ssb_crb and ssb_subcarrier_offset are given in 15kHz SCS*/ - nr_init_frame_parms0(fp,mu,Ncp,N_RB_DL); - fp->ssb_start_subcarrier = (12 * n_ssb_crb + ssb_subcarrier_offset)/(1<ssb_start_subcarrier = (12 * n_ssb_crb + ssb_subcarrier_offset); return 0; } @@ -286,6 +302,8 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp) LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP); LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe); LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame); + LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq); + LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq); } diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index e136e8a770..f0a1abe0ac 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -377,8 +377,8 @@ void phy_config_request(PHY_Config_t *phy_config); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); -int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index); -int nr_init_frame_parms(nfapi_nr_config_request_t *config, NR_DL_FRAME_PARMS *frame_parms); +int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb); +int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag); void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 3c54e0bd28..cb001f9dc4 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -788,8 +788,9 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, int16_t Ravg[2]; Ravg[0]=0; Ravg[1]=0; - int16_t iv, rv, phase_idx; - __m128i avg128U1, avg128U2, R[3], mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + int16_t iv, rv, phase_idx = 0; + __m128i avg128U1, avg128U2, R[3], mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3; + // round(tan((pi/4)*[1:1:N]/N)*pow2(15)) int16_t alpha[128] = {201, 402, 603, 804, 1006, 1207, 1408, 1610, 1811, 2013, 2215, 2417, 2619, 2822, 3024, 3227, 3431, 3634, 3838, 4042, 4246, 4450, 4655, 4861, 5066, 5272, 5479, 5686, 5893, 6101, 6309, 6518, 6727, 6937, 7147, 7358, 7570, 7782, 7995, 8208, 8422, 8637, 8852, 9068, 9285, 9503, 9721, 9940, 10160, 10381, 10603, 10825, 11049, 11273, 11498, 11725, 11952, 12180, 12410, 12640, 12872, 13104, 13338, 13573, 13809, 14046, 14285, 14525, 14766, 15009, 15253, 15498, 15745, 15993, 16243, 16494, 16747, 17001, 17257, 17515, 17774, 18035, 18298, 18563, 18829, 19098, 19368, 19640, 19915, 20191, 20470, 20750, 21033, 21318, 21605, 21895, 22187, 22481, 22778, 23078, 23380, 23685, 23992, 24302, 24615, 24931, 25250, 25572, 25897, 26226, 26557, 26892, 27230, 27572, 27917, 28266, 28618, 28975, 29335, 29699, 30067, 30440, 30817, 31198, 31583, 31973, 32368, 32767}; // compute log2_maxh (output_shift) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 4d296a7872..2b6d998b73 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2001,6 +2001,11 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->ue_type = ulsch_pdu->ulsch_pdu_rel13.ue_type; AssertFatal(harq_pid ==0 || ulsch->ue_type == NOCE, "Harq PID is not zero for BL/CE UE\n"); + if(ulsch_pdu->ulsch_pdu_rel13.repetition_number >1) // Fill the Harq process parameters in the first Rep only + { + return; + } + //AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n"); if(ulsch->harq_processes[harq_pid]->nb_rb == 0) { LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id); @@ -2009,6 +2014,10 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->harq_processes[harq_pid]->frame = frame; ulsch->harq_processes[harq_pid]->subframe = subframe; ulsch->harq_processes[harq_pid]->handled = 0; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ulsch->harq_processes[harq_pid]->repetition_number = ulsch_pdu->ulsch_pdu_rel13.repetition_number ; + ulsch->harq_processes[harq_pid]->total_number_of_repetitions = ulsch_pdu->ulsch_pdu_rel13.total_number_of_repetitions ; +#endif ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start; ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; ulsch->harq_processes[harq_pid]->dci_alloc = 1; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 80e7b6f8cd..6595158f1a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -42,6 +42,7 @@ #include "common/utils/LOG/log.h" #include "targets/RT/USER/lte-softmodem.h" #include +#include "executables/thread-common.h" //#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_FREE 1 @@ -57,9 +58,8 @@ uint64_t runtime, uint64_t deadline, uint64_t period);*/ -extern WORKER_CONF_t get_thread_worker_conf(void); -extern volatile int oai_exit; +extern volatile int oai_exit; void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { int i, r, aa, layer; @@ -99,7 +99,14 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { } } -LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS *frame_parms) { + +LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo, + unsigned char Mdlharq, + uint32_t Nsoft, + unsigned char N_RB_DL, + uint8_t abstraction_flag, + LTE_DL_FRAME_PARMS *frame_parms) +{ LTE_eNB_DLSCH_t *dlsch; unsigned char exit_flag = 0,i,j,r,aa,layer; int re; @@ -221,6 +228,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ return(NULL); } + void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) { unsigned char Mdlharq; unsigned char i,j,r; @@ -257,8 +265,6 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) { } - - int dlsch_encoding_2threads0(te_params *tep) { LTE_eNB_DLSCH_t *dlsch = tep->dlsch; unsigned int G = tep->G; @@ -358,7 +364,6 @@ void *te_thread(void *param) { } - int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, unsigned char *a, uint8_t num_pdcch_symbols, @@ -548,6 +553,8 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); } + + int dlsch_encoding_all(PHY_VARS_eNB *eNB, unsigned char *a, uint8_t num_pdcch_symbols, @@ -812,10 +819,3 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); } - - - - - - - diff --git a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c index 48951ffdd0..c13876f29a 100644 --- a/openair1/PHY/LTE_TRANSPORT/lte_mcs.c +++ b/openair1/PHY/LTE_TRANSPORT/lte_mcs.c @@ -118,8 +118,7 @@ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb) { } } - -int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol) { +int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_order, uint8_t subframe, uint8_t symbol) { int rb,re_pbch_sss=0; int rb_alloc_ind,nsymb; nsymb = (frame_parms->Ncp==NORMAL) ? 14 : 12; @@ -205,7 +204,7 @@ int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_ord return(re_pbch_sss); } -int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe) { +int adjust_G(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_order, uint8_t subframe) { int rb,re_pbch_sss=0; uint8_t rb_alloc_ind; @@ -286,7 +285,16 @@ int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_orde return(0); } -int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe,uint8_t beamforming_mode) { +int get_G(LTE_DL_FRAME_PARMS *frame_parms, + uint16_t nb_rb, + uint32_t *rb_alloc, + uint8_t mod_order, + uint8_t Nl, + uint8_t num_pdcch_symbols, + int frame, + uint8_t subframe, + uint8_t beamforming_mode) +{ int G_adj; if (is_pmch_subframe(frame,subframe,frame_parms) == 0) { @@ -319,8 +327,16 @@ int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint } } - -int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe,uint8_t beamforming_mode) { +int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms, + uint16_t nb_rb, + uint32_t *rb_alloc, + uint8_t mod_order, + uint8_t Nl, + uint8_t num_pdcch_symbols, + int frame, + uint8_t subframe, + uint8_t beamforming_mode) +{ //int G_adj; /*if (is_pmch_subframe(frame,subframe,frame_parms) == 0) { G_adj= adjust_G(frame_parms,rb_alloc,mod_order,subframe); @@ -353,13 +369,10 @@ int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb return((int)frame_parms->N_RB_DL * mod_order * 120); } - // following function requires dlsch_tbs_full.h #include "PHY/LTE_TRANSPORT/dlsch_tbs_full.h" -unsigned char SE2I_TBS(float SE, - unsigned char N_PRB, - unsigned char symbPerRB) { +unsigned char SE2I_TBS(float SE, unsigned char N_PRB, unsigned char symbPerRB) { unsigned char I_TBS= -1; int throughPutGoal = 0; short diffOld = TBStable[0][N_PRB-1] - throughPutGoal; // always positive because of unsigned arithmetic @@ -393,7 +406,6 @@ unsigned char SE2I_TBS(float SE, } //added for ALU icic purpose - uint8_t Get_SB_size(uint8_t n_rb_dl) { if(n_rb_dl<27) return 4; @@ -402,6 +414,4 @@ uint8_t Get_SB_size(uint8_t n_rb_dl) { else return 8; } - - //end ALU's algo diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index 67c627ca00..a80023c744 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -314,6 +314,12 @@ typedef struct { // int calibration_flag; /// delta_TF for power control int32_t delta_TF; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + // PUSCH Repetition Number for the current SF + uint32_t repetition_number ; + // PUSCH Total number of repetitions + uint32_t total_number_of_repetitions; +#endif } LTE_UL_eNB_HARQ_t; typedef struct { diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index e324f76c2b..59fa853c4d 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -553,12 +553,18 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) int G = ulsch_harq->G; unsigned int E; decoder_if_t *tc; + static int32_t pusch_rep_buffer[3*(6144+64)]; + int max_Ncb; if (llr8_flag == 0) tc = *decoder16; else tc = *decoder8; + if(ulsch_harq->repetition_number == 1){ + memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions + } + for (r=0; rC; r++) { // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); // Get Turbo interleaver parameters @@ -592,7 +598,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) 0, //Uplink 1, ulsch_harq->rvidx, - (ulsch_harq->round==0)?1:0, // clear + (ulsch_harq->rvidx==0)?1:0, // clear ulsch_harq->Qm, 1, r, @@ -602,6 +608,27 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) } stop_meas(&eNB->ulsch_rate_unmatching_stats); + + max_Ncb = 3*ulsch_harq->RTC[r]*32 ; + + if(ulsch_harq->total_number_of_repetitions > 1) + { + if (ulsch_harq->rvidx==1) + { // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1 + for (int nn=0;nnw[r][nn] ; + } + } + if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions) + { + for (int nn=0;nnw[r][nn] = pusch_rep_buffer[nn] ; + } + } + } + r_offset += E; start_meas(&eNB->ulsch_deinterleaving_stats); sub_block_deinterleaving_turbo(4+Kr, diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index ab3271c61c..79e220ac37 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -50,6 +50,7 @@ #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "modulation_eNB.h" +#include "nr_modulation.h" #include "common/utils/LOG/vcd_signal_dumper.h" int beam_precoding(int32_t **txdataF, @@ -135,3 +136,33 @@ int beam_precoding_one_eNB(int32_t **txdataF, } return 0; } + + +int nr_beam_precoding(int32_t **txdataF, + int32_t **txdataF_BF, + NR_DL_FRAME_PARMS *frame_parms, + int32_t ***beam_weights, + int slot, + int symbol, + int aa, + int nb_antenna_ports) +{ + + + uint8_t p; + + // clear txdata_BF[aa][re] for each call of ue_spec_beamforming + memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); + + for (p=0; pL_ssb >> p) & 0x01) { + multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size], + (int16_t*)beam_weights[p][aa], + (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], + 0, + frame_parms->ofdm_symbol_size, + 15); + } + } + return 0; +} diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 40099f4739..5c8fce3c38 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -24,7 +24,7 @@ extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; void nr_modulation(uint32_t *in, - uint16_t length, + uint32_t length, uint16_t mod_order, int16_t *out) { @@ -51,9 +51,10 @@ void nr_modulation(uint32_t *in, } void nr_layer_mapping(int16_t **mod_symbs, - uint8_t n_layers, - uint16_t n_symbs, - int16_t **tx_layers) { + uint8_t n_layers, + uint16_t n_symbs, + int16_t **tx_layers) { + LOG_D(PHY,"Doing layer mapping for %d layers, %d symbols\n",n_layers,n_symbs); switch (n_layers) { @@ -120,6 +121,103 @@ void nr_layer_mapping(int16_t **mod_symbs, } } +void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, + uint8_t n_layers, + uint16_t n_symbs, + int16_t **tx_layers) { + + int16_t *mod_symbs; + + switch (n_layers) { + + case 1: + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + for (int i=0; i>15; + tx_layers[0][(i<<1)+1] = (mod_symbs[(i<<1)+1]*AMP)>>15; + } + break; + + case 2: + case 3: + case 4: + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + + for (int i=0; i>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15; + } + } + break; + + case 5: + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + + for (int i=0; i>1; i++) + for (int l=0; l<2; l++) { + tx_layers[l][i<<1] = (mod_symbs[((i<<1)+l)<<1]*AMP)>>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<1)+l)<<1)+1]*AMP)>>15; + } + + mod_symbs = (int16_t *)ulsch_ue[1]->d_mod; + + for (int i=0; i>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; + } + break; + + case 6: + for (int q=0; q<2; q++){ + + mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; + + for (int i=0; i>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; + } + } + break; + + case 7: + mod_symbs = (int16_t *)ulsch_ue[1]->d_mod; + + for (int i=0; i>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15; + } + + mod_symbs = (int16_t *)ulsch_ue[0]->d_mod; + + for (int i=0; i>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; + } + break; + + case 8: + for (int q=0; q<2; q++){ + + mod_symbs = (int16_t *)ulsch_ue[q]->d_mod; + + for (int i=0; i>2; i++) + for (int l=0; l<3; l++) { + tx_layers[l][i<<1] = (mod_symbs[((i<<2)+l)<<1]*AMP)>>15; + tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15; + } + } + break; + + default: + AssertFatal(0, "Invalid number of layers %d\n", n_layers); + } +} + void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH) { diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 249a92e8e3..706b4dc113 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -25,6 +25,7 @@ #include #include "PHY/defs_nr_common.h" #include "PHY/defs_gNB.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #define DMRS_MOD_ORDER 2 @@ -36,7 +37,7 @@ */ void nr_modulation(uint32_t *in, - uint16_t length, + uint32_t length, uint16_t mod_order, int16_t *out); @@ -52,6 +53,18 @@ void nr_layer_mapping(int16_t **mod_symbs, uint16_t n_symbs, int16_t **tx_layers); +/*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3 + @param[in] ulsch_ue, double Pointer to NR_UE_ULSCH_t struct + @param[in] n_layers, number of layers + @param[in] n_symbs, number of modulated symbols + @param[out] tx_layers, modulated symbols for each layer +*/ + +void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue, + uint8_t n_layers, + uint16_t n_symbs, + int16_t **tx_layers); + /*! \brief This function implements the OFDM front end processor on reception (FEP) @@ -80,4 +93,14 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, */ void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH); -#endif \ No newline at end of file +int nr_beam_precoding(int32_t **txdataF, + int32_t **txdataF_BF, + NR_DL_FRAME_PARMS *frame_parms, + int32_t ***beam_weights, + int slot, + int symbol, + int aa, + int nb_antenna_ports +); + +#endif diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index b23fd2e2bf..cbeeca1327 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -86,6 +86,8 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input ) { + if(nb_symbols == 0) return; + short temp[4096*4] __attribute__((aligned(32))); unsigned short i,j; short k; diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index c00fef5929..11aaf1f78e 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -36,10 +36,10 @@ #endif*/ int nr_slot_fep(PHY_VARS_NR_UE *ue, - unsigned char symbol, - unsigned char Ns, - int sample_offset, - int no_prefix) + unsigned char symbol, + unsigned char Ns, + int sample_offset, + int no_prefix) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; @@ -131,8 +131,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #ifdef DEBUG_FEP // if (ue->frame <100) - /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx,Ns, symbol, - nb_prefix_samples,nb_prefix_samples0,slot_offset,sample_offset,rx_offset,frame_length_samples); + /*LOG_I(PHY,*/printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n", + ue->proc.proc_rxtx[(Ns)&1].frame_rx, Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples); #endif if (symbol==0) { @@ -192,7 +192,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #ifdef DEBUG_FEP // if (ue->frame <100) - printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol,rx_offset); + printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol, rx_offset); #endif } diff --git a/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c new file mode 100644 index 0000000000..9c4d1fcc93 --- /dev/null +++ b/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c @@ -0,0 +1,71 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c +* \brief TA estimation for TA updates +* \author Ahmed Hussein +* \date 2019 +* \version 0.1 +* \company Fraunhofer IIS +* \email: ahmed.hussein@iis.fraunhofer.de +* \note +* \warning +*/ + +#include "PHY/types.h" +#include "PHY/defs_gNB.h" +#include "PHY/phy_extern.h" +#include "nr_ul_estimation.h" + +int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) +{ + int temp, i, aa, max_pos = 0, max_val = 0; + short Re, Im; + uint8_t cyclic_shift = 0; + + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id]; + int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time; + + int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size); + + for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { + temp = 0; + + for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; + temp += (Re*Re/2) + (Im*Im/2); + } + + if (temp > max_val) { + max_pos = i; + max_val = temp; + } + } + + if (max_pos > frame_parms->ofdm_symbol_size/2) + max_pos = max_pos - frame_parms->ofdm_symbol_size; + + + return max_pos - sync_pos; +} + diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c new file mode 100644 index 0000000000..16fc94a59f --- /dev/null +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -0,0 +1,397 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#include + +#include "nr_ul_estimation.h" +#include "PHY/NR_REFSIG/nr_refsig.h" +#include "PHY/NR_UE_ESTIMATION/filt16a_32.h" + +//#define DEBUG_CH + + +int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + uint8_t gNB_offset, + unsigned char Ns, + unsigned short p, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pusch) +{ + int pilot[3280] __attribute__((aligned(16))); + unsigned char aarx; + unsigned short k; + unsigned int pilot_cnt; + int16_t ch[2],*pil,*rxF,*ul_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; + int ch_offset,symbol_offset, length_dmrs, UE_id = 0; + unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config + int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(32))); + int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time; + +#ifdef DEBUG_CH + FILE *debug_ch_est; + debug_ch_est = fopen("debug_ch_est.txt","w"); +#endif + + //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1]; + + uint8_t nushift; + int **ul_ch_estimates = gNB->pusch_vars[UE_id]->ul_ch_estimates; + int **rxdataF = gNB->common_vars.rxdataF; + + nushift = (p>>1)&1; + gNB->frame_parms.nushift = nushift; + + ch_offset = gNB->frame_parms.ofdm_symbol_size*symbol; + + symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol; + + k = bwp_start_subcarrier; + int re_offset = k; + +/* +#ifdef DEBUG_CH + printf("PUSCH Channel Estimation : gNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", gNB_offset,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size, + gNB->frame_parms.Ncp,l,Ns,k, symbol); +#endif +*/ + switch (nushift) { + case 0: + fl = filt8_l0; + fm = filt8_m0; + fr = filt8_r0; + fmm = filt8_mm0; + fml = filt8_m0; + fmr = filt8_mr0; + fdcl = filt8_dcl0; + fdcr = filt8_dcr0; + fdclh = filt8_dcl0_h; + fdcrh = filt8_dcr0_h; + break; + + case 1: + fl = filt8_l1; + fm = filt8_m1; + fr = filt8_r1; + fmm = filt8_mm1; + fml = filt8_ml1; + fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; + break; + + default: + printf("pusch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return(-1); + break; + } + + + //------------------generate DMRS------------------// + + length_dmrs = 1; //to update from pusch config + + nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs); + + nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch[gNB_offset][Ns][0], &pilot[0], 1000, 0, nb_rb_pusch); + + //------------------------------------------------// + + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + + pil = (int16_t *)&pilot[0]; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + + memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); + +#ifdef DEBUG_PUSCH + printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL); + printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset); + printf("rxF addr %p p %d\n", rxF,p); + printf("ul_ch addr %p nushift %d\n",ul_ch,nushift); +#endif + //if ((gNB->frame_parms.N_RB_UL&1)==0) { + + // Treat first 2 pilots specially (left edge) + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PUSCH + printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("data 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fl, + ch, + ul_ch, + 8); + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + //for (int i= 0; i<8; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PUSCH + printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fml, + ch, + ul_ch, + 8); + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + //printf("ul_ch addr %p\n",ul_ch); + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PUSCH + printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fmm, + ch, + ul_ch, + 8); + + //for (int i= 0; i<16; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; + + for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt+=2) { + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_CH + fprintf(debug_ch_est, "pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + //printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fm, + ch, + ul_ch, + 8); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fmm, + ch, + ul_ch, + 8); + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; + + } + + // Treat first 2 pilots specially (right edge) + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fm, + ch, + ul_ch, + 8); + + //for (int i= 0; i<8; i++) + //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); + printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fmr, + ch, + ul_ch, + 8); + + pil+=2; + re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ul_ch+=8; + + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); +#ifdef DEBUG_PUSCH + printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); +#endif + multadd_real_vector_complex_scalar(fr, + ch, + ul_ch, + 8); + + + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[0]; + pil += (idxPil-2); + ul_ch += (idxDC-4); + ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + // for proper allignment of SIMD vectors + if((gNB->frame_parms.N_RB_UL&1)==0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + ul_ch-4, + 8); + + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcr, + ch, + ul_ch-4, + 8); + } else { + + multadd_real_vector_complex_scalar(fdclh, + ch, + ul_ch, + 8); + + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcrh, + ch, + ul_ch, + 8); + } + + } +#ifdef DEBUG_PDSCH + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + for(uint16_t idxP=0; idxPframe_parms.ofdm_symbol_size*sizeof(int32_t)); + memcpy(temp_in_ifft_0, &ul_ch_estimates[aarx][symbol_offset], nb_rb_pusch * NR_NB_SC_PER_RB * sizeof(int32_t)); + + switch (gNB->frame_parms.ofdm_symbol_size) { + case 128: + idft128((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 256: + idft256((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 512: + idft512((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 1024: + idft1024((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 1536: + idft1536((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 2048: + idft2048((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 4096: + idft4096((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + case 8192: + idft8192((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + + default: + idft512((int16_t*) temp_in_ifft_0, + (int16_t*) ul_ch_estimates_time[aarx], + 1); + break; + } + } + +#ifdef DEBUG_CH + fclose(debug_ch_est); +#endif + + return(0); +} diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h new file mode 100644 index 0000000000..125c166f7d --- /dev/null +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -0,0 +1,52 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __NR_UL_ESTIMATION_DEFS__H__ +#define __NR_UL_ESTIMATION_DEFS__H__ + + +#include "PHY/defs_gNB.h" +/** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ + * @{ + */ + + +/*! +\brief This function performs channel estimation including frequency interpolation +\param gNB Pointer to gNB PHY variables +\param Ns slot number (0..19) +\param p +\param symbol symbol within slot +\param bwp_start_subcarrier, first allocated subcarrier +\param nb_rb_pusch, number of allocated RBs for this UE +*/ + + int32_t nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, + uint8_t gNB_offset, + unsigned char Ns, + unsigned short p, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pusch); + +int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); + +#endif diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 9b02d2b1af..5c4f218512 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -55,7 +55,7 @@ int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit); void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell); void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell); uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); -uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); +uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); #undef EXTERN diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index e0c17bfb75..182f8b6215 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -36,6 +36,8 @@ #include "refsig_defs_ue.h" #include "PHY/defs_nr_UE.h" +#include "nr_refsig.h" +#include "PHY/defs_gNB.h" /*Table 7.4.1.1.2-1/2 from 38.211 */ int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}}; @@ -48,14 +50,67 @@ short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,2 short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170}; +int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, + unsigned int Ns, + unsigned int *nr_gold_pusch, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pusch_rb) +{ + int8_t w,config_type; + short *mod_table; + unsigned char idx=0; + + typedef int array_of_w[2]; + array_of_w *wf; + array_of_w *wt; + + config_type = 0; //to be updated by higher layer + + wf = (config_type==0) ? wf1 : wf2; + wt = (config_type==0) ? wt1 : wt2; + + if (config_type > 1) + LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", config_type); + + if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) { + if (gNB->frame_parms.Ncp == NORMAL) { + + for (int i=0; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); + ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; + ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; +#ifdef DEBUG_PUSCH + printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", config_type, p, nb_pusch_rb); + printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); + printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1), + (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]); +#endif + } + } else { + LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n"); + } + } else { + LOG_E(PHY,"Illegal p %d PUSCH DMRS port\n",p); + } + + return(0); +} + + int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, - unsigned int Ns, - unsigned int *nr_gold_pdsch, - int32_t *output, - unsigned short p, - unsigned char lp, - unsigned short nb_pdsch_rb) + unsigned int Ns, + unsigned int *nr_gold_pdsch, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pdsch_rb) { int8_t w,config_type; short *mod_table; @@ -101,15 +156,15 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned int Ns, - unsigned int *nr_gold_pdcch, - int32_t *output, - unsigned short p, - unsigned short nb_rb_coreset) -{ +int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, + uint8_t eNB_offset, + unsigned int Ns, + unsigned int *nr_gold_pdcch, + int32_t *output, + unsigned short p, + unsigned short nb_rb_coreset) +{ uint8_t idx=0; //uint8_t pdcch_rb_offset =0; //nr_gold_pdcch += ((int)floor(ue->frame_parms.ssb_start_subcarrier/12)+pdcch_rb_offset)*3/32; @@ -121,8 +176,8 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, ((int16_t*)output)[(i<<1)+1] = nr_rx_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; #ifdef DEBUG_PDCCH if (i<8) - printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pdcch[(i<<1)>>5], (((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1],&output[0]); + printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d addr %p\n", i, idx, nr_gold_pdcch[(i<<1)>>5], (((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1), + (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1],&output[0]); #endif } } @@ -130,7 +185,10 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, return(0); } -int nr_pbch_dmrs_rx(int symbol,unsigned int *nr_gold_pbch,int32_t *output ) + +int nr_pbch_dmrs_rx(int symbol, + unsigned int *nr_gold_pbch, + int32_t *output) { int m,m0,m1; uint8_t idx=0; @@ -164,6 +222,3 @@ int nr_pbch_dmrs_rx(int symbol,unsigned int *nr_gold_pbch,int32_t *output ) return(0); } - - - diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index 1492d7f03f..7057adef21 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -26,11 +26,11 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB) unsigned int x1, x2; uint16_t Nid, i_ssb, i_ssb2; unsigned char Lmax, l, n_hf, N_hf; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; uint8_t reset; - Nid = cfg->sch_config.physical_cell_id.value; + Nid = cfg->cell_config.phy_cell_id.value; Lmax = fp->Lmax; N_hf = (Lmax == 4)? 2:1; @@ -65,7 +65,7 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid) for (uint8_t symb=0; symbsymbols_per_slot; symb++) { reset = 1; - x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1)); + x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1)) + (Nid<<1); for (uint32_t n=0; nsymbols_per_slot; symb++) { reset = 1; x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid)); + LOG_D(PHY,"DMRS slot %d, symb %d x2 %x\n",slot,symb,x2); for (uint32_t n=0; nframe_parms.Nid_cell; + + //printf("gold pdsch nid %d lbar %d\n",nid,lbar); + + for (ns=0; ns<20; ns++) { + + for (l=0; l>1) ^ (x2>>2) ^ (x2>>3))<<31); + + // skip first 50 double words (1600 bits) + for (n=1; n<50; n++) { + x1 = (x1>>1) ^ (x1>>4); + x1 = x1 ^ (x1<<31) ^ (x1<<28); + x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); + x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); + //printf("x1 : %x, x2 : %x\n",x1,x2); + } + + for (n=0; n>1) ^ (x1>>4); + x1 = x1 ^ (x1<<31) ^ (x1<<28); + x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); + x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); + gNB->nr_gold_pusch[nscid][ns][l][n] = x1^x2; + // if ((ns==2)&&(l==0)) + //printf("n=%d : c %x\n",n,x1^x2); + } + + } + } + } +} diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index ad26356abb..39ab13b1f1 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -100,7 +100,7 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue, x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28); ue->nr_gold_pdcch[0][ns][l][n] = x1^x2; - //printf("n=%d : c %x\n",n,x1^x2); + // if (ns==1 && l==0) printf("n=%d : c %x\n",n,x1^x2); } } } @@ -133,7 +133,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, x2tmp0 = ((14*ns+(lbar+l)+1)*((nid<<1)+1))<<17; x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit - + LOG_D(PHY,"UE DMRS slot %d, symb %d, lbar %d, x2 %x, nscid %d\n",ns,l,lbar,x2,nscid); //printf("ns %d gold pdsch x2 %d\n",ns,x2); x1 = 1+ (1<<31); @@ -148,7 +148,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, //printf("x1 : %x, x2 : %x\n",x1,x2); } - for (n=0; n<52; n++) { + for (n=0; n>1) ^ (x1>>4); x1 = x1 ^ (x1<<31) ^ (x1<<28); x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index cb165eed5e..e1bfa1420d 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -39,4 +39,13 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB); void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid); void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid); +void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs); + +int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, + unsigned int Ns, + unsigned int *nr_gold_pusch, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pusch_rb); #endif diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c index 1a64c8902c..8521a2618f 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c @@ -54,7 +54,9 @@ * *********************************************************************/ -int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling) +int16_t *base_sequence_less_than_36(unsigned int M_ZC, + unsigned int u, + unsigned int scaling) { char *phi_table; int16_t *rv_overbar; @@ -77,7 +79,7 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned case 30: break; default: - printf("function base_sequence_less_than 36_: unsupported base sequence size : %d \n", M_ZC); + printf("function base_sequence_less_than 36_: unsupported base sequence size : %u \n", M_ZC); assert(0); break; } @@ -121,7 +123,10 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned * *********************************************************************/ -int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, unsigned int u, unsigned int v, unsigned int scaling) +int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, + unsigned int u, + unsigned int v, + unsigned int scaling) { int16_t *rv_overbar; unsigned int N_ZC; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index a48ed7e37b..c661fbd292 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -42,8 +42,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, nfapi_nr_rnti_type_e rnti_type, - uint16_t N_RB, - nfapi_nr_config_request_t *config) { + uint16_t N_RB) { uint16_t size = 0; switch(format) { @@ -52,7 +51,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, /// 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, config) - size; // Padding to match 1_0 size + 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; @@ -130,7 +129,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, } void nr_pdcch_scrambling(uint32_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t *out) { @@ -138,7 +137,6 @@ void nr_pdcch_scrambling(uint32_t *in, uint32_t x1, x2, s=0; reset = 1; x2 = (n_RNTI<<16) + Nid; - for (int i=0; i>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f); - //printf("nr_pdcch_scrambling: in %d seq 0x%08x => out %d\n",((*in)>>(i&0x1f))&1,s,((*out)>>(i&0x1f))&1); } } -uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, + +uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, - NR_DL_FRAME_PARMS frame_parms, - nfapi_nr_config_request_t config) { + NR_DL_FRAME_PARMS frame_parms) { + int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration - uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD]; - uint16_t dmrs_offset=0; uint16_t cset_start_sc; uint8_t cset_start_symb, cset_nsymb; int k,l,k_prime,dci_idx, dmrs_idx; - nr_cce_t cce; - nr_reg_t reg; - nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE]; /*First iteration: single DCI*/ - NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0]; - nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params; - /*The coreset is initialised - * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 - * or the rb_offset for other coresets - * in time: by its first slot and its first symbol*/ - if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1) { + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15; + + + // find coreset descriptor + + int rb_offset; + int n_rb; + + AssertFatal(pdcch_pdu==NULL || ul_dci_pdu==NULL,"Can't handle both DL and UL DCI in same slot\n"); + + if (pdcch_pdu) pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15; + else if (ul_dci_pdu) pdcch_pdu_rel15 = &ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15; + + get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); + + // compute rb_offset and n_prb based on frequency allocation + + if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) { cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + - pdcch_params.rb_offset)*NR_NB_SC_PER_RB; + rb_offset)*NR_NB_SC_PER_RB; } else - cset_start_sc = frame_parms.first_carrier_offset + pdcch_params.rb_offset*NR_NB_SC_PER_RB; + cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB; - cset_start_symb = pdcch_params.first_symbol; - cset_nsymb = pdcch_params.n_symb; - dci_idx = 0; - LOG_D(PHY, "Coreset rb_offset %d\n",pdcch_params.rb_offset); - LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); - // DMRS length is per OFDM symbol - uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)? - (pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) - uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE) - LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length); + for (int d=0;dnumDlDci;d++) { + /*The coreset is initialised + * in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0 + * or the rb_offset for other coresets + * in time: by its first slot and its first symbol*/ - /// DMRS QPSK modulation - /*There is a need to shift from which index the pregenerated DMRS sequence is used - * see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/ - if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) { - for (int symb=cset_start_symb; symb>5; - - dmrs_offset = (pdcch_params.rb_offset*3)&0x1f; - LOG_D(PHY, "PDCCH DMRS offset %d\n", dmrs_offset); - } - - for (int symb=cset_start_symb; symb>5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f); -#ifdef DEBUG_PDCCH_DMRS - //printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]); -#endif - } - - nr_modulation(dmrs_seq, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated - } else + cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; + cset_nsymb = pdcch_pdu_rel15->DurationSymbols; + dci_idx = 0; + LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d\n",rb_offset,n_rb); + LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb); + // DMRS length is per OFDM symbol + AssertFatal(pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED, + "Interleaved CCE REG MAPPING not supported\n"); + uint32_t dmrs_length = (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED)? + (n_rb*6) : (pdcch_pdu_rel15->AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) + uint32_t encoded_length = pdcch_pdu_rel15->AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE) + LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType); + dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset + + /// DMRS QPSK modulation + for (int symb=cset_start_symb; symbDurationSymbols; symb++) { + nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated - + #ifdef DEBUG_PDCCH_DMRS - - for (int i=0; i>1; i++) - if (dmrs_offset) - printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5], - mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); - else - printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, - gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); - + + for (int i=0; i>1; i++) + printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, + gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); + #endif - } - - /// DCI payload processing - // CRC attachment + Scrambling + Channel coding + Rate matching - uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; - uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? pdcch_params.rnti:0; - uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? - pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value; - t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); - polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr); + } + + /// DCI payload processing + // CRC attachment + Scrambling + Channel coding + Rate matching + uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; + uint16_t n_RNTI = pdcch_pdu_rel15->RNTI[d]; + uint16_t Nid = pdcch_pdu_rel15->ScramblingId[d]; + + t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, + pdcch_pdu_rel15->PayloadSizeBits[d], + pdcch_pdu_rel15->AggregationLevel[d], + 0,NULL); + polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->Payload[d], encoder_output, n_RNTI,1,currentPtr); #ifdef DEBUG_CHANNEL_CODING - printf("polar rnti %d\n",pdcch_params.rnti); - printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", - dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1]); - printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); - - for (int i=0; i>5; i++) - printf("[%d]->0x%08x \t", i,encoder_output[i]); - - printf("\n"); + printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->PayloadSizeBits[d],pdcch_pdu_rel15->AggregationLevel[d]); + printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", + ((uint64_t*)pdcch_pdu_rel15->Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->Payload[d])[1]); + printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); + + for (int i=0; i>5; i++) + printf("[%d]->0x%08x \t", i,encoder_output[i]); + + printf("\n"); #endif - /// Scrambling - uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0}; - nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output); + /// Scrambling + uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0}; + nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output); #ifdef DEBUG_CHANNEL_CODING - printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \ + printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \ [6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n", - scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5], - scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] ); + scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5], + scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] ); #endif - /// QPSK modulation - int16_t mod_dci[NR_MAX_DCI_SIZE>>1]; - nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated + /// QPSK modulation + int16_t mod_dci[NR_MAX_DCI_SIZE>>1]; + nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_DCI - - for (int i=0; i>1; i++) - printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] ); - + + for (int i=0; i>1; i++) + printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] ); + #endif + + /// Resource mapping + + if (cset_start_sc >= frame_parms.ofdm_symbol_size) + cset_start_sc -= frame_parms.ofdm_symbol_size; + + /*Reorder REG list for a freq first mapping*/ + uint8_t nb_regs = pdcch_pdu_rel15->AggregationLevel[d]*NR_NB_REG_PER_CCE; - /// Resource mapping - - if (cset_start_sc >= frame_parms.ofdm_symbol_size) - cset_start_sc -= frame_parms.ofdm_symbol_size; - - /*Reorder REG list for a freq first mapping*/ - uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0}; - uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE; - uint8_t regs_per_symb = nb_regs/cset_nsymb; - - for (int cce_idx=0; cce_idx>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; -#ifdef DEBUG_PDCCH_DMRS - printf("symbol %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); -#endif - k+=4; - - if (k >= frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; - - dmrs_idx++; - } - } - } - - /*Now mapping the encoded DCI based on newly constructed REG list - * and the DMRS for the precoder granularity same as REG bundle*/ - for (int reg_idx=0; reg_idx= frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; - - l = cset_start_symb + reg.symb_idx; - dmrs_idx = (reg.reg_idx/cset_nsymb)*3; - k_prime = 0; - - for (int m=0; m>1) * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp>>1) * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; -#ifdef DEBUG_PDCCH_DMRS - printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); -#endif - dmrs_idx++; - } - - k_prime++; - } else { // DCI payload - ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15; -#ifdef DEBUG_DCI - printf("l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); -#endif - dci_idx++; - } - - k++; - + /*Mapping the encoded DCI along with the DMRS */ + for (int reg_idx=0; reg_idx= frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; - } - } - + k -= frame_parms.ofdm_symbol_size; + + l = cset_start_symb + ((reg_idx/cset_nsymb)%cset_nsymb); + + // dmrs index depends on reference point for k according to 38.211 7.4.1.3.2 + if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) + dmrs_idx = (reg_idx/cset_nsymb)*3; + else + dmrs_idx = ((reg_idx/cset_nsymb)+rb_offset)*3; + + k_prime = 0; + + for (int m=0; mCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) { + ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (2*amp * mod_dmrs[l][dmrs_idx<<1]) >> 15; + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (2*amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; +#ifdef DEBUG_PDCCH_DMRS + printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); +#endif + dmrs_idx++; + } + + k_prime++; + } else { // DCI payload + ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dci[dci_idx<<1]) >> 15; + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dci[(dci_idx<<1) + 1]) >> 15; +#ifdef DEBUG_DCI + printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); +#endif + dci_idx++; + } + + k++; + + if (k >= frame_parms.ofdm_symbol_size) + k -= frame_parms.ofdm_symbol_size; + } // m + } // reg_idx + } // for (int d=0;dnumDlDci;d++) return 0; } + diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index f246eaf18e..047139aa63 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -27,29 +27,31 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, nfapi_nr_rnti_type_e rnti_type, - uint16_t N_RB, - nfapi_nr_config_request_t *config); + uint16_t N_RB); -uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, +uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, - NR_DL_FRAME_PARMS frame_parms, - nfapi_nr_config_request_t config); + NR_DL_FRAME_PARMS frame_parms); void nr_pdcch_scrambling(uint32_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t *out); void nr_fill_dci(PHY_VARS_gNB *gNB, int frame, - int slot, - NR_gNB_DCI_ALLOC_t *dci_alloc, - nfapi_nr_dl_config_dci_dl_pdu *pdu); + int slot); -void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t *dci_alloc, uint16_t n_shift, uint8_t m); +void nr_fill_ul_dci(PHY_VARS_gNB *gNB, + int frame, + int slot); +void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m); + +void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); #endif //__PHY_NR_TRANSPORT_DCI__H diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 1c5b041657..ccec73d40e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -32,15 +32,18 @@ #include "nr_dci.h" -#define DEBUG_FILL_DCI +//#define DEBUG_FILL_DCI #include "nr_dlsch.h" -void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) { +/* + Original version to keep code for Y that needs to be moved to MAC + +void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint16_t n_shift, uint8_t m) { nr_cce_t* cce; nr_reg_t* reg; - nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params = &dci_alloc->pdcch_params; + nfapi_nr_dl_config_pdcch_pdu_rel15_t* pdcch_pdu = gNB->pdcch_pdu.pdcch; uint8_t L = dci_alloc->L; uint8_t bsize = pdcch_params->reg_bundle_size; @@ -54,7 +57,7 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); N_cce = N_reg / NR_NB_REG_PER_CCE; - /*Max number of candidates per aggregation level -- SIB1 configured search space only*/ + //Max number of candidates per aggregation level -- SIB1 configured search space only M_s_max = (L==4)?4:(L==8)?2:1; if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON) @@ -113,6 +116,84 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m } } +*/ + +void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) { + + nr_cce_t* cce; + nr_reg_t* reg; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15; + int bsize = pdcch_pdu_rel15->RegBundleSize; + int R = pdcch_pdu_rel15->InterleaverSize; + int n_shift = pdcch_pdu_rel15->ShiftIndex; + + + //Max number of candidates per aggregation level -- SIB1 configured search space only + + + int n_rb,rb_offset; + + get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); + + + int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols; + int C; + + for (int d=0;dnumDlDci;d++) { + int L = pdcch_pdu_rel15->AggregationLevel[d]; + + if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) + AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); + + if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { + uint16_t assertFatalCond = (N_reg%(bsize*R)); + AssertFatal(assertFatalCond == 0,"CCE to REG interleaving: Invalid configuration leading to non integer C (N_reg %us, bsize %d R %d)\n",N_reg, bsize, R); + C = N_reg/(bsize*R); + } + + LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->CceIndex[d]); + for (uint8_t cce_idx=0; cce_idxcce_list[d][cce_idx]; + cce->cce_idx = pdcch_pdu_rel15->CceIndex[d] + cce_idx; + LOG_D(PHY, "cce_idx %d\n", cce->cce_idx); + + if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { + LOG_D(PHY, "Interleaved CCE to REG mapping\n"); + uint8_t j = cce->cce_idx, j_prime; + uint8_t r,c,idx; + + for (uint8_t bundle_idx=0; bundle_idxreg_list[reg_idx]; + reg->reg_idx = bsize*idx + reg_idx; + reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB; + reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols; + LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); + } + } + } + else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED + LOG_D(PHY, "Non interleaved CCE to REG mapping\n"); + for (uint8_t reg_idx=0; reg_idxreg_list[reg_idx]; + reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx; + reg->start_sc_idx = (reg->reg_idx/pdcch_pdu_rel15->DurationSymbols) * NR_NB_SC_PER_RB; + reg->symb_idx = reg->reg_idx % pdcch_pdu_rel15->DurationSymbols; + LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx); + } + + } + + } + } +} + /*static inline uint64_t dci_field(uint64_t field, uint8_t size) { uint64_t ret = 0; for (int i=0; idci_pdu; - memset((void*)dci_pdu,0,2*sizeof(uint64_t)); - nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &pdcch_pdu->dci_dl_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &pdcch_pdu->pdcch_params_rel15; - - - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15; NR_gNB_DLSCH_t *dlsch; - uint16_t N_RB = params_rel15->n_RB_BWP; - uint8_t fsize=0, pos=0, cand_idx=0; + for (int i=0;inumDlDci;i++) { + + uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i]; - - int dlsch_id = find_nr_dlsch(params_rel15->rnti,gNB,SEARCH_EXIST_OR_FREE); - if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){ - LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",params_rel15->rnti,dlsch_id); - return; - } - - dlsch = gNB->dlsch[dlsch_id][0]; - - dlsch->slot_tx[slot] = 1; - dlsch->harq_ids[frame%2][slot] = pdu_rel15->harq_pid; - AssertFatal(pdu_rel15->harq_pid < 8 && pdu_rel15->harq_pid >= 0, - "illegal harq_pid %d\n",pdu_rel15->harq_pid); - - dlsch->harq_mask |= (1<harq_pid); - dlsch->rnti = params_rel15->rnti; - - dci_alloc->L = 8; - memcpy((void*)&dci_alloc->pdcch_params, (void*)params_rel15, sizeof(nfapi_nr_dl_config_pdcch_parameters_rel15_t)); - dci_alloc->size = nr_get_dci_size(dci_alloc->pdcch_params.dci_format, - dci_alloc->pdcch_params.rnti_type, - N_RB, - cfg); - - AssertFatal(dci_alloc->size<=64, "DCI sizes above 64 bits not yet supported"); - n_shift = (dci_alloc->pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)? - cfg->sch_config.physical_cell_id.value : dci_alloc->pdcch_params.shift_index; - nr_fill_cce_list(dci_alloc, n_shift, cand_idx); - - /// Payload generation - switch(params_rel15->dci_format) { - - - case NFAPI_NR_DL_DCI_FORMAT_1_0: - switch(params_rel15->rnti_type) { - case NFAPI_NR_RNTI_RA: - - // Freq domain assignment - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos=fsize; - *dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_alloc->size-pos,*dci_pdu); -#endif - // Time domain assignment - pos+=4; - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,dci_alloc->size-pos,*dci_pdu); -#endif - // VRB to PRB mapping - - pos++; - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,dci_alloc->size-pos,*dci_pdu); -#endif - // MCS - pos+=5; - *dci_pdu |= ((uint64_t)pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"mcs %d (5 bits)=> %d (0x%lx)\n",pdu_rel15->mcs,dci_alloc->size-pos,*dci_pdu); -#endif - // TB scaling - pos+=2; - *dci_pdu |= ((uint64_t)pdu_rel15->tb_scaling&0x3)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",pdu_rel15->tb_scaling,dci_alloc->size-pos,*dci_pdu); -#endif - break; - - case NFAPI_NR_RNTI_C: - - // indicating a DL DCI format 1bit - pos++; - *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",pdu_rel15->format_indicator,1,N_RB,dci_alloc->size-pos,*dci_pdu); -#endif - - // Freq domain assignment (275rb >> fsize = 16) - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - pos+=fsize; - *dci_pdu |= (((uint64_t)pdu_rel15->frequency_domain_assignment&((1<size-pos)); - -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,*dci_pdu); -#endif - - uint16_t is_ra = 1; - for (int i=0; ifrequency_domain_assignment>>i)&1)) { - is_ra = 0; - break; + int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE); + if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){ + LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->RNTI[i],dlsch_id); + return; } - if (is_ra) //fsize are all 1 38.212 p86 - { - // ra_preamble_index 6 bits - pos+=6; - *dci_pdu |= ((pdu_rel15->ra_preamble_index&0x3f)<<(dci_alloc->size-pos)); - - // UL/SUL indicator 1 bit - pos++; - *dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos); - - // SS/PBCH index 6 bits - pos+=6; - *dci_pdu |= ((pdu_rel15->ss_pbch_index&0x3f)<<(dci_alloc->size-pos)); - - // prach_mask_index 4 bits - pos+=4; - *dci_pdu |= ((pdu_rel15->prach_mask_index&0xf)<<(dci_alloc->size-pos)); - - } //end if - - else { - - // Time domain assignment 4bit - - pos+=4; - *dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,4,dci_alloc->size-pos,*dci_pdu); -#endif - - // VRB to PRB mapping 1bit - pos++; - *dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->vrb_to_prb_mapping,1,dci_alloc->size-pos,*dci_pdu); -#endif - - // MCS 5bit //bit over 32, so dci_pdu ++ - pos+=5; - *dci_pdu |= (pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"MCS %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->mcs,5,dci_alloc->size-pos,*dci_pdu); -#endif - - // New data indicator 1bit - pos++; - *dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"NDI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->ndi,1,dci_alloc->size-pos,*dci_pdu); -#endif - - // Redundancy version 2bit - pos+=2; - *dci_pdu |= (pdu_rel15->rv&0x3)<<(dci_alloc->size-pos); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"RV %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->rv,2,dci_alloc->size-pos,*dci_pdu); -#endif - - // HARQ process number 4bit - pos+=4; - *dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->harq_pid,4,dci_alloc->size-pos,*dci_pdu); -#endif - - // Downlink assignment index 2bit - pos+=2; - *dci_pdu |= ((pdu_rel15->dai&3)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"DAI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->dai,2,dci_alloc->size-pos,*dci_pdu); -#endif - - // TPC command for scheduled PUCCH 2bit - pos+=2; - *dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"TPC %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->tpc,2,dci_alloc->size-pos,*dci_pdu); -#endif - - // PUCCH resource indicator 3bit - pos+=3; - *dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pucch_resource_indicator,3,dci_alloc->size-pos,*dci_pdu); -#endif - - // PDSCH-to-HARQ_feedback timing indicator 3bit - pos+=3; - *dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos)); -#ifdef DEBUG_FILL_DCI - LOG_D(PHY,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->pdsch_to_harq_feedback_timing_indicator,3,dci_alloc->size-pos,*dci_pdu); -#endif - - } //end else - break; - - case NFAPI_NR_RNTI_P: - - // Short Messages Indicator – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_alloc->size-pos++); - // Short Messages – 8 bits - for (int i=0; i<8; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->short_messages>>(7-i))&1)<<(dci_alloc->size-pos++); - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4 bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++); - // MCS 5 bit - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - - // TB scaling 2 bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_alloc->size-pos++); - - - break; - - case NFAPI_NR_RNTI_SI: - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4 bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++); - // MCS 5bit //bit over 32, so dci_pdu ++ - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - - break; - - case NFAPI_NR_RNTI_TC: - // indicating a DL DCI format 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++); - // Freq domain assignment 0-16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4 bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++); - // MCS 5bit //bit over 32, so dci_pdu ++ - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // New data indicator 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - // HARQ process number 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++); - - // Downlink assignment index – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->dai>>(1-i))&1)<<(dci_alloc->size-pos++); - // TPC command for scheduled PUCCH – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++); + dlsch = gNB->dlsch[dlsch_id][0]; + int harq_pid = 0;//extract_harq_pid(i,pdu_rel15); + dlsch->slot_tx[slot] = 1; + dlsch->harq_ids[frame%2][slot] = harq_pid; + AssertFatal(harq_pid < 8 && harq_pid >= 0, + "illegal harq_pid %d\n",harq_pid); + + dlsch->harq_mask |= (1<rnti = pdcch_pdu_rel15->RNTI[i]; + + nr_fill_cce_list(gNB,0); + /* + LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); + LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); + */ + + } + +} +void nr_fill_ul_dci(PHY_VARS_gNB *gNB, + int frame, + int slot) { + + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15; + + + for (int i=0;inumDlDci;i++) { + + uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i]; + + // if there's no DL DCI then generate CCE list + if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0); + /* + LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); + LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); + */ - // LOG_D(PHY, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n", - // dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]); - - - // PDSCH-to-HARQ_feedback timing indicator – 3 bits - for (int i=0; i<3; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_alloc->size-pos++); - - break; - } - break; - - case NFAPI_NR_UL_DCI_FORMAT_0_0: - switch(params_rel15->rnti_type) - { - case NFAPI_NR_RNTI_C: - // indicating a DL DCI format 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++); - // Freq domain assignment max 16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // Frequency hopping flag – 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++); - // MCS 5 bit - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // New data indicator 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - // HARQ process number 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++); - - // TPC command for scheduled PUSCH – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++); - - // Padding bits - for(int a = pos;a<32;a++) - *dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++); - - // UL/SUL indicator – 1 bit - if (cfg->pucch_config.pucch_GroupHopping.value) - *dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++); - - break; - - case NFAPI_NR_RNTI_TC: - - // indicating a DL DCI format 1bit - *dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++); - // Freq domain assignment max 16 bit - fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); - for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++); - // Time domain assignment 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++); - // Frequency hopping flag – 1 bit - *dci_pdu |= ((uint64_t)pdu_rel15->frequency_hopping_flag&1)<<(dci_alloc->size-pos++); - // MCS 5 bit - for (int i=0; i<5; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++); - // New data indicator 1bit - *dci_pdu |= ((uint64_t)pdu_rel15->ndi&1)<<(dci_alloc->size-pos++); - // Redundancy version 2bit - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++); - // HARQ process number 4bit - for (int i=0; i<4; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++); - - // TPC command for scheduled PUSCH – 2 bits - for (int i=0; i<2; i++) - *dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++); - - // Padding bits - for(int a = pos;a<32;a++) - *dci_pdu |= ((uint64_t)pdu_rel15->padding&1)<<(dci_alloc->size-pos++); - - // UL/SUL indicator – 1 bit - if (cfg->pucch_config.pucch_GroupHopping.value) - *dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++); - - break; - } - break; } - LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]); - LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx); - } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c new file mode 100644 index 0000000000..d26a52f157 --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools_common.c @@ -0,0 +1,62 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/NR_TRANSPORT/nr_dci_tools_common.c + * \brief + * \author + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: + * \note + * \warning + */ + +#include "nr_dci.h" + +//#define DEBUG_FILL_DCI + +#include "nr_dlsch.h" + + +void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { + + uint8_t count=0, start=0, start_set=0; + + uint64_t bitmap = (((uint64_t)FreqDomainResource[0])<<37)| + (((uint64_t)FreqDomainResource[1])<<29)| + (((uint64_t)FreqDomainResource[2])<<21)| + (((uint64_t)FreqDomainResource[3])<<13)| + (((uint64_t)FreqDomainResource[4])<<5)| + (((uint64_t)FreqDomainResource[5])>>3); + + for (int i=0; i<45; i++) + if ((bitmap>>(44-i))&1) { + count++; + if (!start_set) { + start = i; + start_set = 1; + } + } + *rb_offset = 6*start; + *n_rb = 6*count; +} + diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 31d321f01c..4518280f6b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -39,11 +39,11 @@ //#define DEBUG_DLSCH_MAPPING void nr_pdsch_codeword_scrambling(uint8_t *in, - uint16_t size, - uint8_t q, - uint32_t Nid, - uint32_t n_RNTI, - uint32_t* out) { + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out) { uint8_t reset, b_idx; uint32_t x1, x2, s=0; @@ -65,174 +65,230 @@ void nr_pdsch_codeword_scrambling(uint8_t *in, } +void nr_pdsch_codeword_scrambling_optim(uint8_t *in, + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out) { + + uint32_t x1, x2, s=0,in32; + + x2 = (n_RNTI<<15) + (q<<14) + Nid; + + s=lte_gold_generic(&x1, &x2, 1); + +#if defined(__AVX2__) + for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) { + in32=_mm256_movemask_epi8(_mm256_slli_epi16(((__m256i*)in)[i],7)); + out[i]=(in32^s); + // printf("in[%d] %x => %x\n",i,in32,out[i]); + s=lte_gold_generic(&x1, &x2, 0); + } +#elif defined(__SSE4__) + _m128i *in128; + for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++) { + in128=&((__m128i*)in)[i<<1]; + ((uint16_t*)&in32)[0] = _mm128_movemask_epi8(_mm256_slli_epi16(in128[0],7)); + ((uint16_t*)&in32)[1] = _mm128_movemask_epi8(_mm256_slli_epi16(in128[1],7)); + out[i]=(in32^s); + s=lte_gold_generic(&x1, &x2, 0); + } + //#elsif defined(__arm__) || defined(__aarch64) + +#else + nr_pdsch_codeword_scrambling(in, + size, + q, + Nid, + n_RNTI, + out); +#endif +} + uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, - NR_gNB_DCI_ALLOC_t *dci_alloc, uint32_t ***pdsch_dmrs, int32_t** txdataF, int16_t amp, int frame, uint8_t slot, NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config, + int xOverhead, time_stats_t *dlsch_encoding_stats, time_stats_t *dlsch_scrambling_stats, - time_stats_t *dlsch_modulation_stats) { + time_stats_t *dlsch_modulation_stats, + time_stats_t *tinput, + time_stats_t *tprep, + time_stats_t *tparity, + time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats, + time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats) { - NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[dci_alloc->harq_pid]; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc->pdcch_params; + int harq_pid = 0; + NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs; int16_t **tx_layers = (int16_t**)dlsch->txdataF; int8_t Wf[2], Wt[2], l0, l_prime[2], delta; - uint16_t nb_symbols = rel15->nb_mod_symbols; - uint8_t Qm = rel15->modulation_order; - uint16_t encoded_length = nb_symbols*Qm; + + uint8_t dmrs_Type = rel15->dmrsConfigType; + int nb_re_dmrs = (dmrs_Type== NFAPI_NR_DMRS_TYPE1) ? 6:4; + uint16_t n_dmrs = ((rel15->rbSize+rel15->rbStart)*nb_re_dmrs)<<1; + int16_t mod_dmrs[n_dmrs<<1]; + + uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; + uint8_t Qm = rel15->qamModOrder[0]; + uint32_t encoded_length = nb_re*Qm; /// CRC, coding, interleaving and rate matching AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); start_meas(dlsch_encoding_stats); - nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms); + nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput, + dlsch_rate_matching_stats, + dlsch_interleaving_stats, + dlsch_segmentation_stats); stop_meas(dlsch_encoding_stats); #ifdef DEBUG_DLSCH -printf("PDSCH encoding:\nPayload:\n"); -for (int i=0; iB>>7; i++) { - for (int j=0; j<16; j++) - printf("0x%02x\t", harq->pdu[(i<<4)+j]); + printf("PDSCH encoding:\nPayload:\n"); + for (int i=0; iB>>7; i++) { + for (int j=0; j<16; j++) + printf("0x%02x\t", harq->pdu[(i<<4)+j]); + printf("\n"); + } + printf("\nEncoded payload:\n"); + for (int i=0; i>3; i++) { + for (int j=0; j<8; j++) + printf("%d", harq->f[(i<<3)+j]); + printf("\t"); + } printf("\n"); -} -printf("\nEncoded payload:\n"); -for (int i=0; i>3; i++) { - for (int j=0; j<8; j++) - printf("%d", harq->f[(i<<3)+j]); - printf("\t"); -} -printf("\n"); #endif + + /// scrambling start_meas(dlsch_scrambling_stats); - for (int q=0; qnb_codewords; q++) + for (int q=0; qNrOfCodewords; q++) memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t)); - uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \ - ((pdcch_params.scrambling_id==0)?pdcch_params.rnti:0) : 0; - uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \ - pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value; - for (int q=0; qnb_codewords; q++) - nr_pdsch_codeword_scrambling(harq->f, - encoded_length, - q, - Nid, - n_RNTI, - scrambled_output[q]); + for (int q=0; qNrOfCodewords; q++) + nr_pdsch_codeword_scrambling_optim(harq->f, + encoded_length, + q, + rel15->dlDmrsScramblingId, + rel15->rnti, + scrambled_output[q]); + stop_meas(dlsch_scrambling_stats); #ifdef DEBUG_DLSCH -printf("PDSCH scrambling:\n"); -for (int i=0; i>8; i++) { - for (int j=0; j<8; j++) - printf("0x%08x\t", scrambled_output[0][(i<<3)+j]); - printf("\n"); -} + printf("PDSCH scrambling:\n"); + for (int i=0; i>8; i++) { + for (int j=0; j<8; j++) + printf("0x%08x\t", scrambled_output[0][(i<<3)+j]); + printf("\n"); + } #endif /// Modulation start_meas(dlsch_modulation_stats); - for (int q=0; qnb_codewords; q++) + for (int q=0; qNrOfCodewords; q++) nr_modulation(scrambled_output[q], encoded_length, Qm, mod_symbs[q]); stop_meas(dlsch_modulation_stats); #ifdef DEBUG_DLSCH -printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_symbols); -for (int i=0; i>3; i++) { - for (int j=0; j<8; j++) { - printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]); - } - printf("\n"); -} -#endif - - - /// Layer mapping - nr_layer_mapping(mod_symbs, - rel15->nb_layers, - nb_symbols, - tx_layers); -#ifdef DEBUG_DLSCH -printf("Layer mapping (%d layers):\n", rel15->nb_layers); -for (int l=0; lnb_layers; l++) - for (int i=0; i<(nb_symbols/rel15->nb_layers)>>3; i++) { + printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re); + for (int i=0; i>3; i++) { for (int j=0; j<8; j++) { - printf("%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]); + printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]); } printf("\n"); } #endif - /// Antenna port mapping - //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 - - /// DMRS QPSK modulation - - int nb_re_dmrs = rel15->dmrs_Type==1?6:4; - uint16_t n_dmrs = (rel15->n_prb*nb_re_dmrs)<<1; - int16_t mod_dmrs[n_dmrs<<1]; - uint8_t dmrs_type = rel15->dmrs_Type; - uint8_t mapping_type = rel15->mapping_type; - - l0 = get_l0(mapping_type, 2);//config->pdsch_config.dmrs_typeA_position.value); - nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + /// Layer mapping + nr_layer_mapping(mod_symbs, + rel15->nrOfLayers, + nb_re, + tx_layers); #ifdef DEBUG_DLSCH -printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_type); -for (int i=0; i>4; i++) { - for (int j=0; j<8; j++) { - printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); - } - printf("\n"); -} + printf("Layer mapping (%d layers):\n", rel15->nrOfLayers); + for (int l=0; lnrOfLayers; l++) + for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) { + printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7); + for (int j=0; j<8; j++) { + printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]); + } + printf("\n"); + } #endif - + /// Antenna port mapping + //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 + + /// DMRS QPSK modulation + + + l0 = get_l0(rel15->dlDmrsSymbPos); + nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + +#ifdef DEBUG_DLSCH + printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type); + for (int i=0; i>4; i++) { + for (int j=0; j<8; j++) { + printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); + } + printf("\n"); + } +#endif + + /// Resource mapping - + // Non interleaved VRB to PRB mapping - uint16_t start_sc = frame_parms->first_carrier_offset + rel15->start_prb*NR_NB_SC_PER_RB; + uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB; if (start_sc >= frame_parms->ofdm_symbol_size) start_sc -= frame_parms->ofdm_symbol_size; #ifdef DEBUG_DLSCH_MAPPING - printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n", - start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols); + printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", + start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers); #endif - - for (int ap=0; apnb_layers; ap++) { + for (int ap=0; apnrOfLayers; ap++) { // DMRS params for this ap - get_Wt(Wt, ap, dmrs_type); - get_Wf(Wf, ap, dmrs_type); - delta = get_delta(ap, dmrs_type); + get_Wt(Wt, ap, dmrs_Type); + get_Wf(Wf, ap, dmrs_Type); + delta = get_delta(ap, dmrs_Type); l_prime[0] = 0; // single symbol ap 0 uint8_t dmrs_symbol = l0+l_prime[0]; #ifdef DEBUG_DLSCH_MAPPING -printf("DMRS params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", -ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); + printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", + 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); #endif uint8_t k_prime=0; uint16_t m=0, n=0, dmrs_idx=0, k=0; - for (int l=rel15->start_symbol; lstart_symbol+rel15->nb_symbols; l++) { + int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) + dmrs_idx = rel15->rbStart*6; + else + dmrs_idx = rel15->rbStart*4; + + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { k = start_sc; - for (int i=0; in_prb*NR_NB_SC_PER_RB; i++) { - if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) { - ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { + if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) { + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING -printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", -dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], -((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); + printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", + dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif dmrs_idx++; k_prime++; @@ -242,12 +298,12 @@ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_ else { - ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * tx_layers[ap][m<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING -printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", -m, l, k, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], -((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", +m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif m++; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index d4a08c5719..d4c12a0ac8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -36,10 +36,10 @@ #include "PHY/defs_gNB.h" void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu); + nfapi_nr_dl_tti_pdcch_pdu dci_pdu, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu); -void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg); +void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg); uint16_t get_RIV(uint16_t rb_start, uint16_t L, uint16_t N_RB); @@ -51,41 +51,45 @@ void nr_get_rbg_parms(NR_BWP_PARMS* bwp, uint8_t config_type); void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list); -void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type); - uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); void nr_pdsch_codeword_scrambling(uint8_t *in, - uint16_t size, - uint8_t q, - uint32_t Nid, - uint32_t n_RNTI, - uint32_t* out); + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out); void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, int slot, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, unsigned char *sdu); uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, - NR_gNB_DCI_ALLOC_t *dci_alloc, uint32_t ***pdsch_dmrs, int32_t** txdataF, int16_t amp, int frame, uint8_t slot, NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config, + int xOverhead, time_stats_t *dlsch_encoding_stats, time_stats_t *dlsch_scrambling_stats, - time_stats_t *dlsch_modulation_stats); + time_stats_t *dlsch_modulation_stats, + time_stats_t *tinput, + time_stats_t *tprep, + time_stats_t *tparity, + time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats, + time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats); -void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); +void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch,uint16_t N_RB); void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); @@ -94,9 +98,16 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); int nr_dlsch_encoding(unsigned char *a,int frame, - uint8_t slot, - NR_gNB_DLSCH_t *dlsch, - NR_DL_FRAME_PARMS* frame_parms); + uint8_t slot, + NR_gNB_DLSCH_t *dlsch, + NR_DL_FRAME_PARMS* frame_parms, + time_stats_t *tinput, + time_stats_t *tprep, + time_stats_t *tparity, + time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats, + time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats); void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 7fd68d5fa9..bd469edcfe 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -39,6 +39,7 @@ #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "SCHED_NR/sched_nr.h" #include "defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -48,12 +49,22 @@ //#define DEBUG_DLSCH_CODING //#define DEBUG_DLSCH_FREE 1 -void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) +void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch,uint16_t N_RB) { int i; int r; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated if (dlsch) { + + if (N_RB != 273) { + a_segments = a_segments*N_RB; + a_segments = a_segments/273; + } + + uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + + #ifdef DEBUG_DLSCH_FREE LOG_D(PHY,"Freeing dlsch %p\n",dlsch); #endif @@ -69,18 +80,34 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) #endif if (dlsch->harq_processes[i]->b) { - free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); //this should be MAX_NR_DLSCH_PAYLOAD_BYTES + free16(dlsch->harq_processes[i]->b,dlsch_bytes); dlsch->harq_processes[i]->b = NULL; #ifdef DEBUG_DLSCH_FREE LOG_D(PHY,"Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b); #endif } + if (dlsch->harq_processes[i]->e) { + free16(dlsch->harq_processes[i]->e,14*N_RB*12*8); + dlsch->harq_processes[i]->e = NULL; +#ifdef DEBUG_DLSCH_FREE + printf("Freeing dlsch process %d e (%p)\n",i,dlsch->harq_processes[i]->e); +#endif + } + + if (dlsch->harq_processes[i]->f) { + free16(dlsch->harq_processes[i]->f,14*N_RB*12*8); + dlsch->harq_processes[i]->f = NULL; +#ifdef DEBUG_DLSCH_FREE + printf("Freeing dlsch process %d f (%p)\n",i,dlsch->harq_processes[i]->f); +#endif + } + #ifdef DEBUG_DLSCH_FREE LOG_D(PHY,"Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c); #endif - for (r=0; rharq_processes[i]->c[r]); @@ -95,7 +122,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) dlsch->harq_processes[i]->d[r] = NULL; } - } + } free16(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t)); dlsch->harq_processes[i] = NULL; } @@ -103,35 +130,31 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) free16(dlsch,sizeof(NR_gNB_DLSCH_t)); dlsch = NULL; - } + } } -NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, +NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, + unsigned char Kmimo, unsigned char Mdlharq, uint32_t Nsoft, - uint8_t abstraction_flag, - NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config) + uint8_t abstraction_flag, + uint16_t N_RB) { NR_gNB_DLSCH_t *dlsch; unsigned char exit_flag = 0,i,r,aa,layer; int re; - unsigned char bw_scaling =1; - uint16_t N_RB = config->rf_config.dl_carrier_bandwidth.value; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated - switch (N_RB) { + if (N_RB != 273) { + a_segments = a_segments*N_RB; + a_segments = a_segments/273; + } - case 106: - bw_scaling =2; - break; - - default: - bw_scaling =1; - break; - } + uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + dlsch = (NR_gNB_DLSCH_t *)malloc16(sizeof(NR_gNB_DLSCH_t)); if (dlsch) { @@ -144,12 +167,12 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, for (layer=0; layerue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*)); - for (aa=0; aa<64; aa++) { + for (aa=0; aa<64; aa++) { dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); for (re=0;reue_spec_bf_weights[layer][aa][re] = 0x00007fff; } - } + } dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH } @@ -170,31 +193,31 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, for (i=0; iharq_processes[i] = (NR_DL_gNB_HARQ_t *)malloc16(sizeof(NR_DL_gNB_HARQ_t)); - LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n", - MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]); + LOG_T(PHY, "Required mem size %d dlsch->harq_processes[%d] %p\n", + dlsch_bytes, i,dlsch->harq_processes[i]); if (dlsch->harq_processes[i]) { bzero(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t)); // dlsch->harq_processes[i]->first_tx=1; - dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); - dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); + dlsch->harq_processes[i]->b = (unsigned char*)malloc16(dlsch_bytes); + dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(dlsch_bytes); if (dlsch->harq_processes[i]->pdu) { - bzero(dlsch->harq_processes[i]->pdu,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); - nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling)>>3); + bzero(dlsch->harq_processes[i]->pdu,dlsch_bytes); + nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (dlsch_bytes)>>3); } else { LOG_D(PHY,"Can't allocate PDU\n"); exit_flag=1; } if (dlsch->harq_processes[i]->b) { - bzero(dlsch->harq_processes[i]->b,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling); + bzero(dlsch->harq_processes[i]->b,dlsch_bytes); } else { LOG_D(PHY,"Can't get b\n"); exit_flag=1; } if (abstraction_flag==0) { - for (r=0; rharq_processes[i]->e = (uint8_t*)malloc16(14*N_RB*12*8); + if (dlsch->harq_processes[i]->e) { + bzero(dlsch->harq_processes[i]->e,14*N_RB*12*8); + } else { + printf("Can't get e\n"); + exit_flag=1; + } + dlsch->harq_processes[i]->f = (uint8_t*)malloc16(14*N_RB*12*8); + if (dlsch->harq_processes[i]->f) { + bzero(dlsch->harq_processes[i]->f,14*N_RB*12*8); + } else { + printf("Can't get f\n"); + exit_flag=1; + } } } else { LOG_D(PHY,"Can't get harq_p %d\n",i); @@ -232,7 +269,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of %ld\n", exit_flag, sizeof(NR_gNB_DLSCH_t)); - free_gNB_dlsch(dlsch); + free_gNB_dlsch(dlsch,N_RB); return(NULL); @@ -260,7 +297,7 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) dlsch->harq_processes[i]->round = 0; for (j=0; j<96; j++) - for (r=0; rharq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = NR_NULL; @@ -269,94 +306,111 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) } } -int nr_dlsch_encoding(unsigned char *a,int frame, - uint8_t slot, - NR_gNB_DLSCH_t *dlsch, - NR_DL_FRAME_PARMS* frame_parms) +int nr_dlsch_encoding(unsigned char *a, + int frame, + uint8_t slot, + NR_gNB_DLSCH_t *dlsch, + NR_DL_FRAME_PARMS* frame_parms, + time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput, + time_stats_t *dlsch_rate_matching_stats,time_stats_t *dlsch_interleaving_stats, + time_stats_t *dlsch_segmentation_stats) { unsigned int G; unsigned int crc=1; - uint8_t harq_pid = dlsch->harq_ids[frame&2][slot]; + uint8_t harq_pid = dlsch->harq_ids[frame%2][slot]; AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid); - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; - uint16_t nb_rb = rel15->n_prb; - uint8_t nb_symb_sch = rel15->nb_symbols; - uint32_t A, Z, F=0; - uint32_t *pz = &Z; - uint8_t mod_order = rel15->modulation_order; - uint16_t Kr=0,r,r_offset=0; - //uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15; + uint16_t nb_rb = rel15->rbSize; + uint8_t nb_symb_sch = rel15->NrOfSymbols; + uint32_t A, Z, Kb, F=0; + uint32_t *Zc = &Z; + uint8_t mod_order = rel15->qamModOrder[0]; + uint16_t Kr=0,r; + uint32_t r_offset=0; uint8_t BG=1; uint32_t E; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; //max tbs - uint8_t nb_re_dmrs = rel15->dmrs_Type==1 ? 6:4; - uint16_t length_dmrs = rel15->dmrs_maxLength; + uint8_t nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4; + uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos); + uint16_t R=rel15->targetCodeRate[0]; float Coderate = 0.0; + uint8_t Nl = 4; - /* - uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char - for(j=0;jtransport_block_size; + A = rel15->TBSize[0]<<3; - G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nb_layers); + G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers); LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); - - - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15->nb_layers); // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet #ifdef DEBUG_DLSCH_CODING LOG_D(PHY,"encoding thinks this is a new packet \n"); #endif - /* + /* int i; LOG_D(PHY,"dlsch (tx): \n"); for (i=0;i<(A>>3);i++) - LOG_D(PHY,"%02x.",a[i]); + LOG_D(PHY,"%02x\n",a[i]); LOG_D(PHY,"\n"); - */ - // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a,A)>>8; - a[A>>3] = ((uint8_t*)&crc)[2]; - a[1+(A>>3)] = ((uint8_t*)&crc)[1]; - a[2+(A>>3)] = ((uint8_t*)&crc)[0]; - //LOG_D(PHY,"CRC %x (A %d)\n",crc,A); - //LOG_D(PHY,"a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); + */ - dlsch->harq_processes[harq_pid]->B = A+24; - // dlsch->harq_processes[harq_pid]->b = a; + if (A > 3824) { + // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a,A)>>8; + a[A>>3] = ((uint8_t*)&crc)[2]; + a[1+(A>>3)] = ((uint8_t*)&crc)[1]; + a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); + + dlsch->harq_processes[harq_pid]->B = A+24; + // dlsch->harq_processes[harq_pid]->b = a; - AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES); + AssertFatal((A/8)+4 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_NR_DLSCH_PAYLOAD_BYTES); - memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); // why is this +4 if the CRC is only 3 bytes? + } + else { + // Add 16-bit crc (polynomial A) to payload + crc = crc16(a,A)>>16; + a[A>>3] = ((uint8_t*)&crc)[1]; + a[1+(A>>3)] = ((uint8_t*)&crc)[0]; + //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]); + + dlsch->harq_processes[harq_pid]->B = A+16; + // dlsch->harq_processes[harq_pid]->b = a; + + AssertFatal((A/8)+3 <= MAX_NR_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_NR_DLSCH_PAYLOAD_BYTES); - nr_segmentation(dlsch->harq_processes[harq_pid]->b, - dlsch->harq_processes[harq_pid]->c, - dlsch->harq_processes[harq_pid]->B, - &dlsch->harq_processes[harq_pid]->C, - &dlsch->harq_processes[harq_pid]->K, - pz, // [hna] pz is Zc - &dlsch->harq_processes[harq_pid]->F); + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc + } + if (R<1000) + Coderate = (float) R /(float) 1024; + else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools + Coderate = (float) R /(float) 2048; - F = dlsch->harq_processes[harq_pid]->F; - Coderate = (float) A /(float) G; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) BG = 2; - } - else{ + else BG = 1; - } + + start_meas(dlsch_segmentation_stats); + Kb = nr_segmentation(dlsch->harq_processes[harq_pid]->b, + dlsch->harq_processes[harq_pid]->c, + dlsch->harq_processes[harq_pid]->B, + &dlsch->harq_processes[harq_pid]->C, + &dlsch->harq_processes[harq_pid]->K, + Zc, + &dlsch->harq_processes[harq_pid]->F, + BG); + stop_meas(dlsch_segmentation_stats); + F = dlsch->harq_processes[harq_pid]->F; Kr = dlsch->harq_processes[harq_pid]->K; #ifdef DEBUG_DLSCH_CODING @@ -364,7 +418,7 @@ int nr_dlsch_encoding(unsigned char *a,int frame, Kr_bytes = Kr>>3; #endif - //LOG_D(PHY,"segment Z %d k %d Kr %d BG %d\n", *pz,dlsch->harq_processes[harq_pid]->K,Kr,BG); + //printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,dlsch->harq_processes[harq_pid]->K,Kr,BG,dlsch->harq_processes[harq_pid]->C); for (r=0; rharq_processes[harq_pid]->C; r++) { //d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0]; @@ -373,30 +427,23 @@ int nr_dlsch_encoding(unsigned char *a,int frame, LOG_D(PHY,"Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F); LOG_D(PHY,"start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C); LOG_D(PHY,"input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]); - for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){ + for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++){ LOG_D(PHY,"%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]); } LOG_D(PHY,"\n"); #endif - //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],Kr,BG,0); - //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],Kr,BG,NULL,NULL,NULL,NULL); + //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0); + //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL); } - //for (int i=0;i<68*384;i++) - // LOG_D(PHY,"channel_input[%d]=%d\n",i,channel_input[i]); + for(int j=0;j<((dlsch->harq_processes[harq_pid]->C-1)/8+1);j++) { + ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG, + dlsch->harq_processes[harq_pid]->C,j, + tinput,tprep,tparity,toutput); + } - - /*LOG_D(PHY,"output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[0][0], dlsch->harq_processes[harq_pid]->d[0][1], dlsch->harq_processes[harq_pid]->d[r][2],dlsch->harq_processes[harq_pid]->d[0][3], dlsch->harq_processes[harq_pid]->d[0][4]); - for (int cnt =0 ; cnt < 66*(*pz); cnt ++){ - LOG_D(PHY,"%d \n", dlsch->harq_processes[harq_pid]->d[0][cnt]); - } - LOG_D(PHY,"\n");*/ - - //ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); - ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL); - #ifdef DEBUG_DLSCH_CODING write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4); @@ -406,48 +453,64 @@ int nr_dlsch_encoding(unsigned char *a,int frame, for (r=0; rharq_processes[harq_pid]->C; r++) { - if (dlsch->harq_processes[harq_pid]->F>0) { - for (int k=(Kr-F-2*(*pz)); kharq_processes[harq_pid]->d[r][k] = NR_NULL; - //if (k<(Kr-F+8)) - //LOG_D(PHY,"r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]); - } - } -#ifdef DEBUG_DLSCH_CODING - LOG_D(PHY,"Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", - r, - G, - Kr*3, - mod_order,nb_rb); -#endif + if (F>0) { + for (int k=(Kr-F-2*(*Zc)); kharq_processes[harq_pid]->d[r][k] = NR_NULL; + //if (k<(Kr-F+8)) + //printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]); + } + } + + #ifdef DEBUG_DLSCH_CODING - LOG_D(PHY,"rvidx in encoding = %d\n", rel15->redundancy_version); + LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]); #endif - E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15->nb_layers, r); + E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15->nrOfLayers, r); +#ifdef DEBUG_DLSCH_CODING + printf("Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n", + r, + dlsch->harq_processes[harq_pid]->C, + G, + E, + F, + Kr-F-2*(*Zc), + mod_order,nb_rb); +#endif + + // for tbslbrm calculation according to 5.4.2.1 of 38.212 + if (rel15->nrOfLayers < Nl) + Nl = rel15->nrOfLayers; + + Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C); + + start_meas(dlsch_rate_matching_stats); nr_rate_matching_ldpc(Ilbrm, Tbslbrm, BG, - *pz, + *Zc, dlsch->harq_processes[harq_pid]->d[r], dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->C, - rel15->redundancy_version, + F, + Kr-F-2*(*Zc), + rel15->rvIndex[0], E); - - + stop_meas(dlsch_rate_matching_stats); #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) LOG_D(PHY,"output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset); #endif - nr_interleaving_ldpc(E, - mod_order, - dlsch->harq_processes[harq_pid]->e+r_offset, - dlsch->harq_processes[harq_pid]->f+r_offset); - + start_meas(dlsch_interleaving_stats); + nr_interleaving_ldpc(E, + mod_order, + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->f+r_offset); + stop_meas(dlsch_interleaving_stats); #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 47a8a6d3f0..ff1f841e47 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -27,6 +27,7 @@ * \company Eurecom * \email: desouza@eurecom.fr * \note + * \warning */ @@ -46,6 +47,7 @@ uint8_t nr_pdsch_default_time_alloc_C_L[15] = {2,2,2,2,2,4,4,4,4,4,7,12,11,6,6}; /// Time domain allocation routines +/* void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, nfapi_nr_dl_config_dci_dl_pdu dci_pdu, nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu) { @@ -73,9 +75,9 @@ void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, case NFAPI_NR_RNTI_RA: case NFAPI_NR_RNTI_TC: - /*AssertFatal(dci_alloc.pdcch_params.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, - "Invalid common search space type %d for RNTI %d, expected %d\n",dci_alloc.pdcch_params.common_search_space_type, - NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, dci_alloc.rnti_type);*/ + //AssertFatal(dci_alloc.pdcch_params.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, + //"Invalid common search space type %d for RNTI %d, expected %d\n",dci_alloc.pdcch_params.common_search_space_type, + //NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, dci_alloc.rnti_type); *alloc_type = (alloc_list_flag) ? NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST : NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A; break; @@ -94,6 +96,7 @@ void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config, } } + uint16_t get_SLIV(uint8_t S, uint8_t L) { return ( (uint16_t)(((L-1)<=7)? (14*(L-1)+S) : (14*(15-L)+(13-S))) ); } @@ -104,7 +107,7 @@ static inline uint8_t get_K0(uint8_t row_idx, uint8_t time_alloc_type) { ((row_idx==6)||(row_idx==7)||(row_idx==15))? 1 : 0); } -/*ideally combine the calculation of L in the same function once the right struct is defined*/ +// ideally combine the calculation of L in the same function once the right struct is defined uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t dmrs_TypeA_Position) { uint8_t idx; @@ -132,6 +135,7 @@ uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t d return 0; // temp warning fix } + void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15,nfapi_nr_config_request_t *cfg) { switch (cfg->subframe_config.dl_cyclic_prefix_type.value) { @@ -241,6 +245,7 @@ void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t p LOG_I(PHY, "PRG parameters for BWP %d location %d N_RB %d:\n", bwp->bwp_id, bwp->location, bwp->N_RB); LOG_I(PHY, "P_prime %d\t start size %d\t endsize %d\t N_PRG %d\n", prg_parms->P_prime, prg_parms->start_size, prg_parms->end_size, prg_parms->N_PRG); } +*/ /// Payload emulation void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) { @@ -257,7 +262,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { AssertFatal(gNB!=NULL,"gNB is null\n"); for (i=0; idlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i); - AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d][0] is null\n",i); + AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i); LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index); if ((gNB->dlsch[i][0]->harq_mask >0) && (gNB->dlsch[i][0]->rnti==rnti)) return i; @@ -269,13 +274,33 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { return first_free_index; } +int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { + + uint16_t i; + int16_t first_free_index=-1; + + AssertFatal(gNB!=NULL,"gNB is null\n"); + for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i); + AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i); + LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index); + if ((gNB->ulsch[i][0]->harq_mask >0) && + (gNB->ulsch[i][0]->rnti==rnti)) return i; + else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; + } + if (type == SEARCH_EXIST) return -1; + if (first_free_index != -1) + gNB->ulsch[first_free_index][0]->rnti = 0; + return first_free_index; +} + void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, int slot, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, uint8_t *sdu) { - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch_pdu->dlsch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &pdsch_pdu->pdsch_pdu_rel15; int dlsch_id = find_nr_dlsch(rel15->rnti,gNB,SEARCH_EXIST); AssertFatal( (dlsch_id>=0) && (dlsch_iddlsch[dlsch_id][0]; NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes; /// DLSCH struct - memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->dlsch_pdu, (void*)dlsch_pdu, sizeof(nfapi_nr_dl_config_dlsch_pdu)); + memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + gNB->num_pdsch_rnti++; AssertFatal(sdu!=NULL,"sdu is null\n"); harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu; } +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu) { + + + int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE); + AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id); + + NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0]; + int harq_pid = ulsch_pdu->pusch_data.harq_process_id; + ulsch->rnti = ulsch_pdu->rnti; + //ulsch->rnti_type; + ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid; + + nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch->harq_processes[harq_pid]->ulsch_pdu; + + LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid); + + + //FK this is still a bad hack. We need to replace the L1 FAPI structures with the new scf ones as well. + rel15_ul->rnti = ulsch_pdu->rnti; + rel15_ul->ulsch_pdu_rel15.start_rb = ulsch_pdu->rb_start; + rel15_ul->ulsch_pdu_rel15.number_rbs = ulsch_pdu->rb_size; + rel15_ul->ulsch_pdu_rel15.start_symbol = ulsch_pdu->start_symbol_index; + rel15_ul->ulsch_pdu_rel15.number_symbols = ulsch_pdu->nr_of_symbols; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; //where should this come from? + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; //where should this come from? + rel15_ul->ulsch_pdu_rel15.Qm = ulsch_pdu->qam_mod_order; + rel15_ul->ulsch_pdu_rel15.mcs = ulsch_pdu->mcs_index; + rel15_ul->ulsch_pdu_rel15.rv = ulsch_pdu->pusch_data.rv_index; + rel15_ul->ulsch_pdu_rel15.n_layers = ulsch_pdu->nrOfLayers; + rel15_ul->ulsch_pdu_rel15.R = ulsch_pdu->target_code_rate; + +} + diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index bb114fa390..c8bdb8beb5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -50,13 +50,13 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms) { int k,l; //int16_t a; int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1]; uint8_t idx=0; - uint8_t nushift = config->sch_config.physical_cell_id.value &3; + uint8_t nushift = config->cell_config.phy_cell_id.value &3; LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift); /// QPSK modulation @@ -220,16 +220,15 @@ void nr_init_pbch_interleaver(uint8_t *interleaver) { } int nr_generate_pbch(NR_gNB_PBCH *pbch, - uint8_t *pbch_pdu, + nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, uint8_t *interleaver, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, uint8_t n_hf, uint8_t Lmax, - uint8_t ssb_index, int sfn, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms) { int k,l,m; //int16_t a; @@ -243,17 +242,18 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ///Payload generation memset((void *)pbch, 0, sizeof(NR_gNB_PBCH)); pbch->pbch_a=0; - + uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex; + uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload; for (int i=0; ipbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<pbch_a |= ((pbch_pdu[i>>3]>>(7-(i&7)))&1)<pbch_a); -#endif + #endif // Extra byte generation for (int i=0; i<4; i++) @@ -265,7 +265,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, for (int i=0; i<3; i++) pbch->pbch_a |= ((ssb_index>>(5-i))&1)<<(29+i); // resp. 6th, 5th and 4th bits of ssb_index else - pbch->pbch_a |= ((config->sch_config.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4) + pbch->pbch_a |= ((config->ssb_table.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4) LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a); @@ -287,7 +287,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1); pbch->pbch_a_prime = 0; - nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask); + nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask); #ifdef DEBUG_PBCH_ENCODING printf("Payload scrambling: nushift %d M %d sfn3 %d sfn2 %d\n", nushift, M, (sfn>>2)&1, (sfn>>1)&1); printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime); @@ -298,8 +298,8 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i); /// CRC, coding and rate matching - polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, - nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL) + polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, 0, + nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL,0,NULL) ); #ifdef DEBUG_PBCH_ENCODING printf("Channel coding:\n"); @@ -312,7 +312,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, /// Scrambling M = NR_POLAR_PBCH_E; nushift = (Lmax==4)? ssb_index&3 : ssb_index&7; - nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0); + nr_pbch_scrambling(pbch, (uint32_t)config->cell_config.phy_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0); #ifdef DEBUG_PBCH_ENCODING printf("Scrambling:\n"); @@ -333,7 +333,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, } /// Resource mapping - nushift = config->sch_config.physical_cell_id.value &3; + nushift = config->cell_config.phy_cell_id.value &3; // PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS ///symbol 1 [0:239] -- 180 mod symbols k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; diff --git a/openair1/PHY/NR_TRANSPORT/nr_pss.c b/openair1/PHY/NR_TRANSPORT/nr_pss.c index e0d7b6ae33..be9e011e60 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pss.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pss.c @@ -28,7 +28,7 @@ int nr_generate_pss( int16_t *d_pss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t* config, + nfapi_nr_config_request_scf_t* config, NR_DL_FRAME_PARMS *frame_parms) { int i,k,l,m; @@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss, int16_t x[NR_PSS_LENGTH]; const int x_initial[7] = {0, 1, 1 , 0, 1, 1, 1}; - uint8_t Nid2 = config->sch_config.physical_cell_id.value % 3; + uint8_t Nid2 = config->cell_config.phy_cell_id.value % 3; /// Sequence generation for (i=0; i < 7; i++) diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c index 8d9bf00639..ad2edadb5f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c @@ -85,13 +85,19 @@ uint8_t get_delta(uint8_t ap, uint8_t config) { return ((config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][2]):(pdsch_dmrs_2[ap][2])); } -uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { +uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { uint16_t dmrs_idx = (dmrs_type)? (6*n+k_prime+delta):((n<<2)+(k_prime<<1)+delta); return dmrs_idx; } -uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position) { - - return ((mapping_type==NFAPI_NR_PDSCH_MAPPING_TYPE_A)?dmrs_typeA_position:0); +uint8_t get_l0(uint16_t dlDmrsSymbPos) { + uint16_t mask=dlDmrsSymbPos; + int l0; + for (l0=0;l0<14;l0++) { + if ((mask&1) == 1) break; + mask>>=1; + } + AssertFatal(l0 < 4,"impossible l0 %d\n",l0); + return (l0); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h index 02f454b7d0..40cc3fbc1b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h @@ -45,6 +45,6 @@ void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config); uint8_t get_delta(uint8_t ap, uint8_t config); -uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); +uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); -uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position); +uint8_t get_l0(uint16_t dlDmrsSymbPos); diff --git a/openair1/PHY/NR_TRANSPORT/nr_sss.c b/openair1/PHY/NR_TRANSPORT/nr_sss.c index 154aca9ffe..7d8b551d7c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sss.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sss.c @@ -27,7 +27,7 @@ int nr_generate_sss( int16_t *d_sss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t* config, + nfapi_nr_config_request_scf_t* config, NR_DL_FRAME_PARMS *frame_parms) { int i,k,l; @@ -39,7 +39,7 @@ int nr_generate_sss( int16_t *d_sss, const int x1_initial[7] = { 1, 0, 0, 0, 0, 0, 0 }; /// Sequence generation - Nid = config->sch_config.physical_cell_id.value; + Nid = config->cell_config.phy_cell_id.value; Nid2 = Nid % 3; Nid1 = (Nid - Nid2)/3; diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c index 6060a04658..cb85992a8e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c @@ -31,27 +31,7 @@ */ #include "nr_transport_common_proto.h" - - -static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) { - return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1)); -} - -static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8_t rnti_type, uint8_t ss_type) { - if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1) && ((rnti_type==NFAPI_NR_RNTI_C)||(rnti_type==NFAPI_NR_RNTI_CS))) - return 2; - else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type!=NFAPI_NR_RNTI_new) && (rnti_type==NFAPI_NR_RNTI_C) && (ss_type==NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)) - return 3; - else if (rnti_type==NFAPI_NR_RNTI_new) - return 3; - else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (rnti_type==NFAPI_NR_RNTI_CS) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1)) - return 2; // Condition mcs_table not configured in sps_config necessary here but not yet implemented - /*else if((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type==NFAPI_NR_RNTI_CS)) - * table_idx = 3; - * Note: the commented block refers to the case where the mcs_table is from sps_config*/ - else - return 1; -} +#include "PHY/CODING/coding_defs.h" uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport.h b/openair1/PHY/NR_TRANSPORT/nr_transport.h index d94b73245e..a485351cd3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport.h @@ -36,7 +36,7 @@ int nr_generate_pss( int16_t *d_pss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -49,7 +49,7 @@ int nr_generate_sss( int16_t *d_sss, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -62,7 +62,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -85,16 +85,15 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, @returns 0 on success */ int nr_generate_pbch(NR_gNB_PBCH *pbch, - uint8_t *pbch_pdu, + nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, uint8_t *interleaver, int32_t *txdataF, int16_t amp, uint8_t ssb_start_symbol, uint8_t n_hf, uint8_t Lmax, - uint8_t ssb_index, int sfn, - nfapi_nr_config_request_t *config, + nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); /*! @@ -105,12 +104,12 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, */ void nr_init_pbch_interleaver(uint8_t *interleaver); -NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, +NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, + unsigned char Kmimo, unsigned char Mdlharq, uint32_t Nsoft, uint8_t abstraction_flag, - NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_config_request_t *config); + uint16_t N_RB); void rx_nr_prach(PHY_VARS_gNB *gNB, int frame, diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index 018e36ce4e..762346048f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -36,20 +36,13 @@ #include "PHY/defs_nr_common.h" -#define MAX_NUM_NR_DLSCH_SEGMENTS 16 -#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS - #define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1 #define NR_PUSCH_y 3 // UCI placeholder bit -/** \brief Computes Q based on I_MCS PDSCH and table_idx. Implements Table 5.1.3.1-2 from 38.214. */ -uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx); -uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx); -void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu); + /** \brief Computes available bits G. */ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t Qm, uint8_t Nl); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 2dbef1d733..8d220a76bb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -65,7 +65,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, */ void nr_ulsch_extract_rbs_single(int **rxdataF, + int **ul_ch_estimates, int **rxdataF_ext, + int **ul_ch_estimates_ext, uint32_t rxdataF_ext_offset, // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment unsigned char symbol, @@ -73,6 +75,54 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned short nb_rb_pusch, NR_DL_FRAME_PARMS *frame_parms); +void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext, + NR_DL_FRAME_PARMS *frame_parms, + NR_gNB_ULSCH_t **ulsch_gNB, + uint8_t symbol, + uint8_t start_symbol, + uint16_t nb_rb); + + +/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal + @param ul_ch_estimates_ext Channel estimates in allocated RBs + @param frame_parms Pointer to frame descriptor + @param avg Pointer to average signal strength + @param pilots_flag Flag to indicate pilots in symbol + @param nb_rb Number of allocated RBs +*/ +void nr_ulsch_channel_level(int **ul_ch_estimates_ext, + NR_DL_FRAME_PARMS *frame_parms, + int32_t *avg, + uint8_t symbol, + uint32_t len, + unsigned short nb_rb); + + +/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation) + @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated + @param ul_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated + @param ul_ch_mag First Channel magnitudes (16QAM/64QAM) + @param ul_ch_magb Second weighted Channel magnitudes (64QAM) + @param rxdataF_comp Compensated received waveform + @param frame_parms Pointer to frame descriptor + @param symbol Symbol on which to operate + @param Qm Modulation order of allocation + @param nb_rb Number of RBs in allocation + @param output_shift Rescaling for compensated output (should be energy-normalizing) +*/ +void nr_ulsch_channel_compensation(int **rxdataF_ext, + int **ul_ch_estimates_ext, + int **ul_ch_mag, + int **ul_ch_magb, + int **rxdataF_comp, + int **rho, + NR_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + uint8_t pilots, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift); + /*! \brief This function implements the idft transform precoding in PUSCH \param z Pointer to input in frequnecy domain, and it is also the output in time domain @@ -102,6 +152,7 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol); @@ -118,6 +169,7 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int32_t **ul_ch_magb, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol); @@ -135,6 +187,22 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int32_t **ul_ch_magb, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol, - uint8_t mod_order); \ No newline at end of file + uint8_t mod_order); + +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu); + +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); + +uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx); + +uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx); + +uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); + +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h index e7af632327..15e66477c3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h @@ -1728,41 +1728,6 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset); -uint8_t nr_dci_decoding_procedure(int s, - int p, - PHY_VARS_NR_UE *ue, - NR_DCI_ALLOC_t *dci_alloc, - NR_SEARCHSPACE_TYPE_t searchSpacetype, - int16_t eNB_id, - uint8_t nr_tti_rx, - uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - crc_scrambled_t *crc_scrambled, - format_found_t *format_found, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]); - -int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - int frame, - uint8_t nr_tti_rx, - uint64_t dci_pdu[2], - uint16_t rnti, - uint8_t dci_length, - NR_DCI_format_t dci_format, - NR_UE_PDCCH *pdcch_vars, - NR_UE_PDSCH *pdsch_vars, - NR_UE_DLSCH_t **dlsch, - NR_UE_ULSCH_t *ulsch, - NR_DL_FRAME_PARMS *frame_parms, - PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - uint8_t beamforming_mode, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES], - NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted); - int nr_rx_pdsch(PHY_VARS_NR_UE *ue, PDSCH_t type, unsigned char eNB_id, @@ -1789,20 +1754,5 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); -int nr_extract_dci_info(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - lte_frame_type_t frame_type, - uint8_t dci_length, - uint16_t rnti, - uint64_t dci_pdu[2], - fapi_nr_dci_pdu_rel15_t *nr_pdci_info_extracted, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - NR_DCI_format_t dci_format, - uint8_t nr_tti_rx, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]); - - /**@}*/ #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 11521563e4..d49f5c8d00 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -32,7 +32,7 @@ #include "PHY/defs_gNB.h" -void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL); NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); @@ -75,7 +75,8 @@ void nr_ulsch_unscrambling(int16_t* llr, void nr_ulsch_procedures(PHY_VARS_gNB *gNB, - gNB_L1_rxtx_proc_t *proc, + int frame_rx, + int slot_rx, int UE_id, uint8_t harq_pid); - +int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 6ca2733120..1eba026fd4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -48,38 +48,55 @@ #include "common/utils/LOG/log.h" #include //#define DEBUG_ULSCH_DECODING +//#define gNB_DEBUG_TRACE #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 *ulsch) +void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL) { int i,r; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated + NR_gNB_ULSCH_t *ulsch = *ulschptr; if (ulsch) { + if (N_RB_UL != 273) { + a_segments = a_segments*N_RB_UL; + a_segments = a_segments/273; + } + + uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment + for (i=0; iharq_processes[i]) { if (ulsch->harq_processes[i]->b) { - free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES); + free16(ulsch->harq_processes[i]->b,ulsch_bytes); ulsch->harq_processes[i]->b = NULL; } - for (r=0; rharq_processes[i]->c[r],(8448)*sizeof(uint8_t)); ulsch->harq_processes[i]->c[r] = NULL; } - for (r=0; rharq_processes[i]->d[r]) { free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t)); ulsch->harq_processes[i]->d[r] = NULL; } } - for (r=0; r<(MAX_NUM_NR_ULSCH_SEGMENTS); r++) { + for (r=0; rharq_processes[i]->w[r]) { + free16(ulsch->harq_processes[i]->w[r],(3*(6144+64))*sizeof(int16_t)); + ulsch->harq_processes[i]->w[r] = NULL; + } + } + for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r]){ nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]); ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL; @@ -90,7 +107,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) } } free16(ulsch,sizeof(NR_gNB_ULSCH_t)); - ulsch = NULL; + *ulschptr = NULL; } } @@ -100,17 +117,14 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 NR_gNB_ULSCH_t *ulsch; uint8_t exit_flag = 0,i,r; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated - switch (N_RB_UL) { - case 106: - bw_scaling =2; - break; + if (N_RB_UL != 273) { + a_segments = a_segments*N_RB_UL; + a_segments = a_segments/273; + } - default: - bw_scaling =1; - break; - } + uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t)); @@ -129,15 +143,15 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t)); - ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->b = (uint8_t*)malloc16(ulsch_bytes); if (ulsch->harq_processes[i]->b) - memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + memset(ulsch->harq_processes[i]->b,0,ulsch_bytes); else exit_flag=3; if (abstraction_flag == 0) { - for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); @@ -154,6 +168,13 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t)); else exit_flag=2; + + ulsch->harq_processes[i]->w[r] = (int16_t*)malloc16((3*(6144+64))*sizeof(int16_t)); + + if (ulsch->harq_processes[i]->w[r]) + memset(ulsch->harq_processes[i]->w[r],0,(3*(6144+64))*sizeof(int16_t)); + else + exit_flag=2; } } } else { @@ -166,8 +187,8 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 } printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag); - free_gNB_ulsch(ulsch); - + free_gNB_ulsch(&ulsch,N_RB_UL); + return(NULL); } @@ -176,99 +197,103 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) unsigned char i, j; if (ulsch) { - ulsch->harq_mask = 0; - ulsch->bundling = 0; - ulsch->beta_offset_cqi_times8 = 0; - ulsch->beta_offset_ri_times8 = 0; - ulsch->beta_offset_harqack_times8 = 0; - ulsch->Msg3_active = 0; - ulsch->Msg3_flag = 0; - ulsch->Msg3_subframe = 0; - ulsch->Msg3_frame = 0; - ulsch->rnti = 0; - ulsch->rnti_type = 0; - ulsch->cyclicShift = 0; - ulsch->cooperation_flag = 0; - ulsch->Mlimit = 0; - ulsch->max_ldpc_iterations = 0; - ulsch->last_iteration_cnt = 0; - ulsch->num_active_cba_groups = 0; - for (i=0;icba_rnti[i] = 0; - for (i=0;iharq_process_id[i] = 0; + ulsch->harq_mask = 0; + ulsch->bundling = 0; + ulsch->beta_offset_cqi_times8 = 0; + ulsch->beta_offset_ri_times8 = 0; + ulsch->beta_offset_harqack_times8 = 0; + ulsch->Msg3_active = 0; + ulsch->Msg3_flag = 0; + ulsch->Msg3_subframe = 0; + ulsch->Msg3_frame = 0; + ulsch->rnti = 0; + ulsch->rnti_type = 0; + ulsch->cyclicShift = 0; + ulsch->cooperation_flag = 0; + ulsch->Mlimit = 0; + ulsch->max_ldpc_iterations = 0; + ulsch->last_iteration_cnt = 0; + ulsch->num_active_cba_groups = 0; + for (i=0;icba_rnti[i] = 0; + for (i=0;iharq_process_id[i] = 0; - for (i=0; iharq_processes[i]){ - /// Nfapi ULSCH PDU - //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu; - ulsch->harq_processes[i]->frame=0; - ulsch->harq_processes[i]->subframe=0; - ulsch->harq_processes[i]->round=0; - ulsch->harq_processes[i]->TPC=0; - ulsch->harq_processes[i]->mimo_mode=0; - ulsch->harq_processes[i]->dci_alloc=0; - ulsch->harq_processes[i]->rar_alloc=0; - ulsch->harq_processes[i]->status=0; - ulsch->harq_processes[i]->subframe_scheduling_flag=0; - ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0; - ulsch->harq_processes[i]->phich_active=0; - ulsch->harq_processes[i]->phich_ACK=0; - ulsch->harq_processes[i]->previous_first_rb=0; - ulsch->harq_processes[i]->handled=0; - ulsch->harq_processes[i]->delta_TF=0; + for (i=0; iharq_processes[i]){ + /// Nfapi ULSCH PDU + //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu; + ulsch->harq_processes[i]->frame=0; + ulsch->harq_processes[i]->subframe=0; + ulsch->harq_processes[i]->round=0; + ulsch->harq_processes[i]->TPC=0; + ulsch->harq_processes[i]->mimo_mode=0; + ulsch->harq_processes[i]->dci_alloc=0; + ulsch->harq_processes[i]->rar_alloc=0; + ulsch->harq_processes[i]->status=0; + ulsch->harq_processes[i]->subframe_scheduling_flag=0; + ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0; + ulsch->harq_processes[i]->phich_active=0; + ulsch->harq_processes[i]->phich_ACK=0; + ulsch->harq_processes[i]->previous_first_rb=0; + ulsch->harq_processes[i]->handled=0; + ulsch->harq_processes[i]->delta_TF=0; - ulsch->harq_processes[i]->TBS=0; - /// Pointer to the payload (38.212 V15.4.0 section 5.1) - //uint8_t *b; - ulsch->harq_processes[i]->B=0; - /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) - //uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; - ulsch->harq_processes[i]->K=0; - ulsch->harq_processes[i]->F=0; - ulsch->harq_processes[i]->C=0; - /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) - //int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; - /// LDPC processing buffer - //t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS]; - ulsch->harq_processes[i]->Z=0; - /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) - //int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; - ulsch->harq_processes[i]->E=0; + ulsch->harq_processes[i]->TBS=0; + /// Pointer to the payload (38.212 V15.4.0 section 5.1) + //uint8_t *b; + ulsch->harq_processes[i]->B=0; + /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) + //uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; + ulsch->harq_processes[i]->K=0; + ulsch->harq_processes[i]->F=0; + ulsch->harq_processes[i]->C=0; + /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) + //int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// LDPC processing buffer + //t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS]; + ulsch->harq_processes[i]->Z=0; + /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) + //int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; + ulsch->harq_processes[i]->E=0; - ulsch->harq_processes[i]->n_DMRS=0; - ulsch->harq_processes[i]->n_DMRS2=0; - ulsch->harq_processes[i]->previous_n_DMRS=0; + ulsch->harq_processes[i]->n_DMRS=0; + ulsch->harq_processes[i]->n_DMRS2=0; + ulsch->harq_processes[i]->previous_n_DMRS=0; - ulsch->harq_processes[i]->cqi_crc_status=0; - for (j=0;jharq_processes[i]->o[j]=0; - ulsch->harq_processes[i]->uci_format=0; - ulsch->harq_processes[i]->Or1=0; - ulsch->harq_processes[i]->Or2=0; - ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0; - ulsch->harq_processes[i]->O_RI=0; - ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0; - ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0; - ulsch->harq_processes[i]->O_ACK=0; - ulsch->harq_processes[i]->V_UL_DAI=0; - /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) - //int8_t q[MAX_CQI_PAYLOAD]; - ulsch->harq_processes[i]->o_RCC=0; - /// coded and interleaved CQI bits - //int8_t o_w[(MAX_CQI_BITS+8)*3]; - /// coded CQI bits - //int8_t o_d[96+((MAX_CQI_BITS+8)*3)]; - for (j=0;jharq_processes[i]->q_ACK[j]=0; - for (j=0;jharq_processes[i]->q_RI[j]=0; - /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled - //uint8_t h[MAX_NUM_CHANNEL_BITS]; - /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - //int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; - } - } + ulsch->harq_processes[i]->cqi_crc_status=0; + for (j=0;jharq_processes[i]->o[j]=0; + ulsch->harq_processes[i]->uci_format=0; + ulsch->harq_processes[i]->Or1=0; + ulsch->harq_processes[i]->Or2=0; + ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0; + ulsch->harq_processes[i]->O_RI=0; + ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0; + ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0; + ulsch->harq_processes[i]->O_ACK=0; + ulsch->harq_processes[i]->V_UL_DAI=0; + /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) + //int8_t q[MAX_CQI_PAYLOAD]; + ulsch->harq_processes[i]->o_RCC=0; + /// coded and interleaved CQI bits + //int8_t o_w[(MAX_CQI_BITS+8)*3]; + /// coded CQI bits + //int8_t o_d[96+((MAX_CQI_BITS+8)*3)]; + for (j=0;jharq_processes[i]->q_ACK[j]=0; + for (j=0;jharq_processes[i]->q_RI[j]=0; + /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled + //uint8_t h[MAX_NUM_CHANNEL_BITS]; + /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + //int16_t w[MAX_NUM_NR_ULSCH_SEGMENTS][3*(6144+64)]; + } + } } } +#ifdef PRINT_CRC_CHECK + static uint32_t prnt_crc_cnt = 0; +#endif + uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t UE_id, short *ulsch_llr, @@ -287,9 +312,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, 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))); + +#ifdef PRINT_CRC_CHECK + prnt_crc_cnt++; +#endif - NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id+1][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]; nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15; @@ -297,11 +326,15 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, 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; + uint8_t kc=255; uint8_t Ilbrm = 0; uint32_t Tbslbrm = 950984; double Coderate = 0.0; @@ -310,6 +343,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint16_t nb_rb = nfapi_ulsch_pdu_rel15->number_rbs; uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols; uint8_t Qm = nfapi_ulsch_pdu_rel15->Qm; + uint16_t R = nfapi_ulsch_pdu_rel15->R; uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs; uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers; uint8_t nb_re_dmrs = nfapi_ulsch_pdu_rel15->nb_re_dmrs; @@ -324,60 +358,37 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (!ulsch_llr) { printf("ulsch_decoding.c: NULL ulsch_llr pointer\n"); - return(ulsch->max_ldpc_iterations); - } - - if (!harq_process) { - printf("ulsch_decoding.c: NULL harq_process pointer\n"); - return(ulsch->max_ldpc_iterations); + return (ulsch->max_ldpc_iterations + 1); } if (!frame_parms) { printf("ulsch_decoding.c: NULL frame_parms pointer\n"); - return(ulsch->max_ldpc_iterations); + return (ulsch->max_ldpc_iterations + 1); } // harq_process->trials[nfapi_ulsch_pdu_rel15->round]++; - - harq_process->TBS = nr_compute_tbs(mcs, nb_rb, number_symbols, nb_re_dmrs, length_dmrs, n_layers); + harq_process->TBS = nr_compute_tbs(Qm, R, nb_rb, number_symbols, nb_re_dmrs*length_dmrs, 0, n_layers); A = harq_process->TBS; - ret = ulsch->max_ldpc_iterations; - - G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers); - // G = 0; - // G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers); + ret = ulsch->max_ldpc_iterations + 1; - LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb); + G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers); + + LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb); if (harq_process->round == 0) { // This is a new packet, so compute quantities regarding segmentation harq_process->B = A+24; - // [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, - &harq_process->C, - &harq_process->K, - &harq_process->Z, // [hna] Z is Zc - &harq_process->F); + if (R<1024) + Coderate = (float) R /(float) 1024; + else + Coderate = (float) R /(float) 2048; - p_decParams->Z = harq_process->Z; - -#ifdef DEBUG_ULSCH_DECODING - printf("ulsch decoding nr segmentation Z %d\n", p_decParams->Z); - if (!frame%100) - printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); -#endif - } - - Coderate = (float) A /(float) G; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - p_decParams->BG = 2; - if (Coderate < 0.3333) { + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + p_decParams->BG = 2; + if (Coderate < 0.3333) { p_decParams->R = 15; kc = 52; } @@ -405,8 +416,23 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } } - //printf("coderate %f kc %d \n", Coderate, kc); + // [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, + &harq_process->C, + &harq_process->K, + &harq_process->Z, // [hna] Z is Zc + &harq_process->F, + 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 nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl); +#endif + } + p_decParams->Z = harq_process->Z; p_decParams->numMaxIter = ulsch->max_ldpc_iterations; @@ -415,36 +441,28 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, err_flag = 0; r_offset = 0; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated - switch (frame_parms->N_RB_UL) { + if (nb_rb != 273) { + a_segments = a_segments*nb_rb; + a_segments = a_segments/273; + } - case 106: - bw_scaling =2; - break; - - default: - bw_scaling =1; - break; - } - - if (harq_process->C > MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling) { - LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling); - return((1+ulsch->max_ldpc_iterations)); + 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); } #ifdef DEBUG_ULSCH_DECODING printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); #endif - opp_enabled=1; + //opp_enabled=1; - Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb" + Kr = harq_process->K; Kr_bytes = Kr>>3; K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers); - for (r=0; rC; r++) { E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r); @@ -494,6 +512,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ///////////////////////// harq_process->e =====> harq_process->d ///////////////////////// + Tbslbrm = nr_compute_tbslbrm(0,nb_rb,nfapi_ulsch_pdu_rel15->n_layers,harq_process->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -503,12 +523,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->C, nfapi_ulsch_pdu_rel15->rv, (harq_process->round==0)?1:0, - E)==-1) { + E, + harq_process->F, + Kr-harq_process->F-2*(p_decParams->Z))==-1) { #if gNB_TIMING_TRACE stop_meas(ulsch_rate_unmatching_stats); #endif LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n"); - return(ulsch->max_ldpc_iterations); + return (ulsch->max_ldpc_iterations + 1); } else { #if gNB_TIMING_TRACE stop_meas(ulsch_rate_unmatching_stats); @@ -523,7 +545,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + 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]); @@ -560,7 +582,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } - for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) { + AssertFatal(kc!=255,""); + j+=(harq_process->F>>3); + // for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) { + for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) { pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } @@ -584,19 +609,24 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, p_procTime); if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - LOG_I(PHY, "Segment %d CRC OK\n",r); - ret = 2; + #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 { - LOG_I(PHY, "CRC NOK\n"); - ret = 1+ulsch->max_ldpc_iterations; + #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++; } - - ret=no_iteration_ldpc; for (int m=0; m < Kr>>3; m ++) { harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; @@ -606,7 +636,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, //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>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + 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 @@ -615,7 +645,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #endif } - if ((err_flag == 0) && (ret>=(1+ulsch->max_ldpc_iterations))) { + 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; @@ -633,16 +663,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (err_flag == 1) { -#if gNB_DEBUG_TRACE - LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", - phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); +#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", + phy_vars_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++; + //harq_process->round++; if (harq_process->round >= ulsch->Mlimit) { harq_process->status = SCH_IDLE; @@ -657,13 +687,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } harq_process->handled = 1; - return((1+ulsch->max_ldpc_iterations)); + return (ulsch->max_ldpc_iterations + 1); } else { -#if gNB_DEBUG_TRACE - LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", - phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); +#ifdef gNB_DEBUG_TRACE + LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n", + phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS); #endif harq_process->status = SCH_IDLE; @@ -694,7 +724,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_ULSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + 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", diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index d70e61e358..b961b592d5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -3,8 +3,13 @@ #include "nr_transport_proto.h" #include "PHY/impl_defs_top.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" +#include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "PHY/defs_nr_common.h" +//#define DEBUG_CH_COMP +//#define DEBUG_RB_EXT +//#define DEBUG_CH_MAG + void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) { @@ -216,7 +221,9 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) } void nr_ulsch_extract_rbs_single(int **rxdataF, + int **ul_ch_estimates, int **rxdataF_ext, + int **ul_ch_estimates_ext, uint32_t rxdataF_ext_offset, // unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment unsigned char symbol, @@ -227,12 +234,22 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, unsigned short start_re, re, nb_re_pusch; unsigned char aarx, is_dmrs_symbol = 0; uint32_t rxF_ext_index = 0; + uint32_t ul_ch0_ext_index = 0; + uint32_t ul_ch0_index = 0; int16_t *rxF,*rxF_ext; + int *ul_ch0,*ul_ch0_ext; + +#ifdef DEBUG_RB_EXT + + printf("--------------------symbol = %d-----------------------\n", symbol); + printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch); + +#endif is_dmrs_symbol = (symbol == 2) ? 1 : 0; //to be updated from config - start_re = frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB); + start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size; nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch; @@ -241,19 +258,710 @@ void nr_ulsch_extract_rbs_single(int **rxdataF, rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; rxF_ext = (int16_t *)&rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6 + ul_ch0 = &ul_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; // DMRS REs are only in symbol 2 (to be updated from config) + ul_ch0_ext = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch]; + for (re = 0; re < nb_re_pusch; re++) { if ( (is_dmrs_symbol && ((re&1) != 0)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A // frame_parms->nushift should be initialized with 0 rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]); rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]); + ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index]; + + #ifdef DEBUG_RB_EXT + printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]); + printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]); + printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index]); + printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index + 1]); + #endif + rxF_ext_index = rxF_ext_index + 2; + ul_ch0_ext_index++; } + ul_ch0_index++; } } } +void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, + NR_DL_FRAME_PARMS *frame_parms, + NR_gNB_ULSCH_t **ulsch_gNB, + uint8_t symbol, + uint8_t pilots, + unsigned short nb_rb) +{ +#if defined(__x86_64__)||defined(__i386__) + + short rb, ch_amp; + unsigned char aatx,aarx; + __m128i *ul_ch128, ch_amp128; + + // Determine scaling amplitude based the symbol + + ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a)); + + LOG_D(PHY,"Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, pilots, nb_rb, frame_parms->Ncp, symbol); + // printf("Scaling PUSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); + + ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 + + for (aatx=0; aatx < frame_parms->nb_antenna_ports_eNB; aatx++) { + for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) { + + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB]; + + if (pilots==1){ + nb_rb = nb_rb>>1; + } + + + for (rb=0;rb>x; + + for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++) + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + //clear average level + avg128U = _mm_setzero_si128(); + + ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; + + for (rb = 0; rb < nb_rb; rb++) { + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x)); + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x)); + avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x)); + ul_ch128+=3; + } + + avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] + + ((int32_t*)&avg128U)[1] + + ((int32_t*)&avg128U)[2] + + ((int32_t*)&avg128U)[3] ) / y; + + } + + _mm_empty(); + _m_empty(); + +#elif defined(__arm__) + + short rb; + unsigned char aatx, aarx, nre = 12, symbol_mod; + int32x4_t avg128U; + int16x4_t *ul_ch128; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) + for (aarx=0; aarxnb_antennas_rx; aarx++) { + //clear average level + avg128U = vdupq_n_s32(0); + // 5 is always a symbol with no pilots for both normal and extended prefix + + ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + + for (rb = 0; rb < nb_rb; rb++) { + // printf("rb %d : ",rb); + // print_shorts("ch",&ul_ch128[0]); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[0], ul_ch128[0])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[1], ul_ch128[1])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[2], ul_ch128[2])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[3], ul_ch128[3])); + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { + ul_ch128+=4; + } else { + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[4], ul_ch128[4])); + avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[5], ul_ch128[5])); + ul_ch128+=6; + } + + /* + if (rb==0) { + print_shorts("ul_ch128",&ul_ch128[0]); + print_shorts("ul_ch128",&ul_ch128[1]); + print_shorts("ul_ch128",&ul_ch128[2]); + } + */ + } + + if (symbol==2) //assume start symbol 2 + nre=6; + else + nre=12; + + avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] + + ((int32_t*)&avg128U)[1] + + ((int32_t*)&avg128U)[2] + + ((int32_t*)&avg128U)[3] ) / (nb_rb*nre); + } + + +#endif +} + +void nr_ulsch_channel_compensation(int **rxdataF_ext, + int **ul_ch_estimates_ext, + int **ul_ch_mag, + int **ul_ch_magb, + int **rxdataF_comp, + int **rho, + NR_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + uint8_t pilots, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift) +{ + +#ifdef DEBUG_CH_COMP + int16_t *rxF, *ul_ch; + int prnt_idx; + + + rxF = (int16_t *)&rxdataF_ext[0][(symbol*nb_rb*12)]; + ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12]; + + printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift); + printf("----------------Before compansation------------------\n"); + + for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){ + + printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]); + printf("ul_ch[%d] = %d\n", prnt_idx, ul_ch[prnt_idx]); + + } + +#endif + +#ifdef DEBUG_CH_MAG + int16_t *ch_mag; + int print_idx; + + + ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*nb_rb*12)]; + + printf("--------------------symbol = %d, mod_order = %d-----------------------\n", symbol, mod_order); + printf("----------------Before computation------------------\n"); + + for (print_idx=0;print_idx<50;print_idx++){ + + printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]); + + } + +#endif + +#if defined(__i386) || defined(__x86_64) + + unsigned short rb; + unsigned char aatx,aarx; + __m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; + QAM_amp128b = _mm_setzero_si128(); + + for (aatx=0; aatxnb_antennas_tx; aatx++) { + + if (mod_order == 4) { + QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = _mm_setzero_si128(); + } else if (mod_order == 6) { + QAM_amp128 = _mm_set1_epi16(QAM64_n1); // + QAM_amp128b = _mm_set1_epi16(QAM64_n2); + } + + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; + ul_ch_mag128 = (__m128i *)&ul_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12]; + ul_ch_mag128b = (__m128i *)&ul_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*nb_rb*12]; + + + for (rb=0; rb2) { + // get channel amplitude if not QPSK + + //print_shorts("ch:",(int16_t*)&ul_ch128[0]); + + mmtmpD0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + + mmtmpD1 = _mm_madd_epi16(ul_ch128[1],ul_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + // store channel magnitude here in a new field of ulsch + + ul_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + ul_ch_mag128b[0] = ul_ch_mag128[0]; + ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128); + ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],1); + + // print_ints("ch: = ",(int32_t*)&mmtmpD0); + // print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); + // print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]); + + ul_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + ul_ch_mag128b[1] = ul_ch_mag128[1]; + ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128); + ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1); + + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + + ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + ul_ch_mag128b[2] = ul_ch_mag128[2]; + + ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128); + ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1); + } + + ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b); + ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1); + + + ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b); + ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1); + + if (pilots==0) { + ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b); + ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1); + } + } + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(ul_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",ul_ch128); + // print_shorts("pack:",rxdataF_comp128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(ul_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",ul_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); + + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",ul_ch128+2); + // print_shorts("pack:",rxdataF_comp128+2); + + ul_ch128+=3; + ul_ch_mag128+=3; + ul_ch_mag128b+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less + ul_ch128+=2; + ul_ch_mag128+=2; + ul_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + } + + } + } + } + + if (rho) { + + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12]; + + for (rb=0; rb=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { + if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size + nb_rb=1+(5*nb_rb/6); + } + else { + pilots=1; + } + } + + for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) { + if (mod_order == 4) { + QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) + QAM_amp128b = vmovq_n_s16(0); + } else if (mod_order == 6) { + QAM_amp128 = vmovq_n_s16(QAM64_n1); // + QAM_amp128b = vmovq_n_s16(QAM64_n2); + } + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch_mag128 = (int16x8_t*)&ul_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch_mag128b = (int16x8_t*)&ul_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12]; + rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12]; + + for (rb=0; rb2) { + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(ul_ch128[0], ul_ch128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(ul_ch128[1], ul_ch128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(ul_ch128[2], ul_ch128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(ul_ch128[3], ul_ch128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + if (pilots==0) { + mmtmpD0 = vmull_s16(ul_ch128[4], ul_ch128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(ul_ch128[5], ul_ch128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + } + + ul_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); + ul_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); + ul_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); + ul_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); + + if (pilots==0) { + ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); + ul_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); + } + } + + mmtmpD0 = vmull_s16(ul_ch128[0], rxdataF128[0]); + //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] + mmtmpD1 = vmull_s16(ul_ch128[1], rxdataF128[1]); + //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]); + //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]); + //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vmull_s16(ul_ch128[2], rxdataF128[2]); + mmtmpD1 = vmull_s16(ul_ch128[3], rxdataF128[3]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + if (pilots==0) { + mmtmpD0 = vmull_s16(ul_ch128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(ul_ch128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + + ul_ch128+=6; + ul_ch_mag128+=3; + ul_ch_mag128b+=3; + rxdataF128+=6; + rxdataF_comp128+=3; + + } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less + ul_ch128+=4; + ul_ch_mag128+=2; + ul_ch_mag128b+=2; + rxdataF128+=4; + rxdataF_comp128+=2; + } + } + } + } + + if (rho) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { + rho128 = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; + ul_ch128_2 = (int16x4_t*)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12]; + for (rb=0; rbframe_parms; - nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; - uint32_t nb_re_pusch; - - if(symbol == rel15_ul->start_symbol) - gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0; + nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; + uint32_t nb_re_pusch, bwp_start_subcarrier; + int avgs; + int avg[4]; - if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1) + pilots = 0; + first_symbol_flag = 0; + + if(symbol == rel15_ul->start_symbol){ + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0; + first_symbol_flag = 1; + } + + if (symbol == rel15_ul->start_symbol){ // [hna] here it is assumed that first carries 6 DMRS REs (dmrs-type 1) nb_re_pusch = rel15_ul->number_rbs * 6; - else + pilots = 1; + } else { nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB; + pilots = 0; + } + + bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; + + //---------------------------------------------------------- + //--------------------- Channel estimation --------------------- + //---------------------------------------------------------- + + if (pilots == 1) + nr_pusch_channel_estimation(gNB, + 0, + nr_tti_rx, + 0, // p + symbol, + bwp_start_subcarrier, + rel15_ul->number_rbs); //---------------------------------------------------------- //--------------------- RBs extraction --------------------- //---------------------------------------------------------- nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, + gNB->pusch_vars[UE_id]->ul_ch_estimates, gNB->pusch_vars[UE_id]->rxdataF_ext, + gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, gNB->pusch_vars[UE_id]->rxdataF_ext_offset, // rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment symbol, @@ -288,6 +1024,44 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, rel15_ul->number_rbs, frame_parms); + nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + gNB->ulsch[UE_id], + symbol, + pilots, + rel15_ul->number_rbs); + + if (first_symbol_flag==1) { + + nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_re_pusch, + rel15_ul->number_rbs); + avgs = 0; + + for (aatx=0;aatxnb_antennas_tx;aatx++) + for (aarx=0;aarxnb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + + gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1; + + } + + nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext, + gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, + gNB->pusch_vars[UE_id]->rxdataF_comp, + (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL, + frame_parms, + symbol, + pilots, + rel15_ul->Qm, + rel15_ul->number_rbs, + gNB->pusch_vars[UE_id]->log2_maxh); + #ifdef NR_SC_FDMA nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch); #endif @@ -296,14 +1070,15 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, //-------------------- LLRs computation -------------------- //---------------------------------------------------------- - nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_ext[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], - gNB->pusch_vars[UE_id]->ul_ch_mag, - gNB->pusch_vars[UE_id]->ul_ch_magb, + nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm], + rel15_ul->number_rbs, nb_re_pusch, symbol, rel15_ul->Qm); - + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index d2d8cdd927..233ecd8de7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -30,7 +30,6 @@ * \warning */ - #include "PHY/defs_nr_common.h" #include "PHY/sse_intrin.h" #include "PHY/impl_defs_top.h" @@ -71,23 +70,20 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol) { + #if defined(__x86_64__) || defined(__i386__) __m128i *rxF = (__m128i*)rxdataF_comp; - // __m128i *ch_mag; // [hna] This should be uncommented once channel estimation is implemented + __m128i *ch_mag; __m128i llr128[2]; uint32_t *llr32; - // [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented - // else ul_ch_mag and ul_ch_magb should be used after channel estimation has benn implemented - __m128i temp_channel; - int16_t one_over_sqrt_2 = 23170; - #elif defined(__arm__) int16x8_t *rxF = (int16x8_t*)&rxdataF_comp; - // int16x8_t *ch_mag; // [hna] This should be uncommented once channel estimation is implemented + int16x8_t *ch_mag; int16x8_t xmm0; int16_t *llr16; #endif @@ -103,21 +99,16 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, llr16 = (int16_t*)ulsch_llr; #endif -// [hna] This should be uncommented once channel estimation is implemented -// ------------------------------------------------------------ -// #if defined(__x86_64__) || defined(__i386__) -// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; -// #elif defined(__arm__) -// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; -// #endif -// ------------------------------------------------------------ +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; +#endif len_mod4 = nb_re&3; nb_re >>= 2; // length in quad words (4 REs) nb_re += (len_mod4 == 0 ? 0 : 1); - temp_channel = _mm_set1_epi16((QAM16_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT)); - for (i=0; i |y_R|, registers of odd index in xmm0-> |y_I| - xmm0 = _mm_subs_epi16(temp_channel,xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 + xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st and 2nd REs llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); // llr128[1] contains the llrs of the 3rd and 4th REs @@ -186,52 +177,43 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, int32_t **ul_ch_mag, int32_t **ul_ch_magb, int16_t *ulsch_llr, + uint32_t nb_rb, uint32_t nb_re, uint8_t symbol) { + #if defined(__x86_64__) || defined(__i386__) __m128i *rxF = (__m128i*)rxdataF_comp; - // __m128i *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented - - // [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented - // else ul_ch_mag and ul_ch_magb should be used after channel estimation has been implemented - __m128i temp_channel[2]; - int16_t one_over_sqrt_2 = 23170; - + __m128i *ch_mag,*ch_magb; #elif defined(__arm__) int16x8_t *rxF = (int16x8_t*)&rxdataF_comp; - // int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented + int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented int16x8_t xmm1,xmm2; #endif int i; unsigned char len_mod4; -// [hna] This should be uncommented once channel estimation is implemented -// ------------------------------------------------------------------------- -// #if defined(__x86_64__) || defined(__i386__) -// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)]; -// ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)]; -// #elif defined(__arm__) -// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)]; -// ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)]; -// #endif -// ------------------------------------------------------------------------- +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)]; + ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)]; + ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)]; +#endif len_mod4 = nb_re&3; nb_re = nb_re>>2; // length in quad words (4 REs) nb_re += ((len_mod4 == 0) ? 0 : 1); - - temp_channel[0] = _mm_set1_epi16((QAM64_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT)); - temp_channel[1] = _mm_set1_epi16((QAM64_n2 * one_over_sqrt_2)>>(2*15-AMP_SHIFT)); + for (i=0; inb_antennas_rx; aa++) { - Re = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; + Re = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -80,7 +80,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment //max_pos_fil = max_pos; - if(subframe == 1) + if(subframe == 0) { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 6df9e0c20e..72ab04c492 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -21,7 +21,7 @@ #include - +#include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "filt16a_32.h" @@ -31,11 +31,11 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned char symbol, - int dmrss, - NR_UE_SSB *current_ssb) + uint8_t eNB_offset, + unsigned char Ns, + unsigned char symbol, + int dmrss, + NR_UE_SSB *current_ssb) { int pilot[200] __attribute__((aligned(16))); unsigned char aarx; @@ -98,8 +98,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -114,8 +113,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; current_ssb->c_re +=ch[0]; @@ -126,8 +124,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) { @@ -138,8 +135,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); + re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -149,12 +145,11 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, current_ssb->c_im +=ch[1]; #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -165,11 +160,10 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, current_ssb->c_im +=ch[1]; #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -180,12 +174,11 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, current_ssb->c_im +=ch[1]; #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } @@ -207,11 +200,15 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t n_hf) { int pilot[200] __attribute__((aligned(16))); - unsigned char aarx; + unsigned char aarx,p; unsigned short k; unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; int ch_offset,symbol_offset; + //int slot_pbch; + //fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; + // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) + //uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; @@ -310,8 +307,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; //for (int i= 0; i<8; i++) @@ -329,8 +325,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -345,8 +340,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; @@ -358,8 +352,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); + re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch += 288; } @@ -367,7 +360,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fl, ch, @@ -378,8 +371,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -387,15 +379,14 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -403,7 +394,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_CH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fr, @@ -411,13 +402,65 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; } + void (*idft)(int16_t *,int16_t *, int); + + switch (ue->frame_parms.ofdm_symbol_size) { + case 128: + idft = idft128; + break; + + case 256: + idft = idft256; + break; + + case 512: + idft = idft512; + break; + + case 1024: + idft = idft1024; + break; + + case 1536: + idft = idft1536; + break; + + case 2048: + idft = idft2048; + break; + + case 3072: + idft = idft3072; + break; + + case 4096: + idft = idft4096; + break; + + default: + printf("unsupported ofdm symbol size \n"); + assert(0); + } + + if( symbol == 3) + { + // do ifft of channel estimate + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) + for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) { + if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) + { + LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, ue->current_thread_id[Ns], symbol, ch_offset); + idft((int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset], + (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); + } + } + } //} @@ -426,14 +469,14 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned char symbol, - unsigned short coreset_start_subcarrier, - unsigned short nb_rb_coreset) + uint8_t eNB_offset, + unsigned char Ns, + unsigned char symbol, + unsigned short coreset_start_subcarrier, + unsigned short nb_rb_coreset) { - int pilot[200] __attribute__((aligned(16))); - unsigned char aarx,p; + + unsigned char aarx; unsigned short k; unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; @@ -441,12 +484,9 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; - uint8_t nushift; int **dl_ch_estimates =ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; - nushift = 1; - ue->frame_parms.nushift = nushift; if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage ch_offset = ue->frame_parms.ofdm_symbol_size ; @@ -467,14 +507,15 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, fr = filt16a_r1; - // generate pilot + // generate pilot + int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { pil = (int16_t *)&pilot[0]; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); @@ -545,12 +586,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, if (k >= ue->frame_parms.ofdm_symbol_size){ k-=ue->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];} + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];} ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fl, ch, @@ -566,7 +607,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -579,7 +620,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDCCH - printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fr, @@ -597,78 +638,24 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, //} } - - void (*idft)(int16_t *,int16_t *, int); - - switch (ue->frame_parms.ofdm_symbol_size) { - case 128: - idft = idft128; - break; - - case 256: - idft = idft256; - break; - - case 512: - idft = idft512; - break; - - case 1024: - idft = idft1024; - break; - - case 1536: - idft = idft1536; - break; - - case 2048: - idft = idft2048; - break; - - case 3072: - idft = idft3072; - break; - - case 4096: - idft = idft4096; - break; - - default: - printf("unsupported ofdm symbol size \n"); - assert(0); - } - - if( (Ns== 1) && (symbol == 0)) - { - // do ifft of channel estimate - for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) - for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) { - if (ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) - { - LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol); - idft((int16_t*) &ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx][0], - (int16_t*) ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); - } - } - } return(0); } int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, - uint8_t eNB_offset, - unsigned char Ns, - unsigned short p, - unsigned char symbol, - unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch) + uint8_t eNB_offset, + unsigned char Ns, + unsigned short p, + unsigned char symbol, + unsigned short bwp_start_subcarrier, + unsigned short nb_rb_pdsch) { - - int pilot[1320] __attribute__((aligned(16))); + int pilot[3280] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr,*fmm; + int16_t ch[2],*pil,*rxF,*dl_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; int ch_offset,symbol_offset; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; @@ -703,6 +690,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, fmm = filt8_mm0; fml = filt8_m0; fmr = filt8_mr0; + fdcl = filt8_dcl0; + fdcr = filt8_dcr0; + fdclh = filt8_dcl0_h; + fdcrh = filt8_dcr0_h; break; case 1: @@ -712,6 +703,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, fmm = filt8_mm1; fml = filt8_ml1; fmr = filt8_m1; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; break; default: @@ -722,11 +717,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot - nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch); + uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12; + int config_type = 0; // needs to be updated from higher layer + nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - pil = (int16_t *)&pilot[0]; + pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + k = k % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; @@ -756,8 +754,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //for (int i= 0; i<8; i++) //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); @@ -772,8 +769,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("dl_ch addr %p\n",dl_ch); @@ -791,8 +787,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; @@ -804,7 +799,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -812,32 +807,30 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fmm, ch, dl_ch, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; } // Treat first 2 pilots specially (right edge) - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fm, ch, @@ -848,15 +841,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])); - printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fmr, ch, @@ -864,22 +856,84 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); - re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); + re_offset = (re_offset+2) % ue->frame_parms.ofdm_symbol_size; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); #ifdef DEBUG_PDSCH - printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); + printf("pilot %u: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif multadd_real_vector_complex_scalar(fr, ch, dl_ch, 8); //} + + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { + dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + pil += (idxPil-2); + dl_ch += (idxDC-4); + dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + // for proper allignment of SIMD vectors + if((ue->frame_parms.N_RB_DL&1)==0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + dl_ch-4, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcr, + ch, + dl_ch-4, + 8); + } else { + multadd_real_vector_complex_scalar(fdclh, + ch, + dl_ch, + 8); + + pil += 4; + re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + multadd_real_vector_complex_scalar(fdcrh, + ch, + dl_ch, + 8); + } + + } + +#ifdef DEBUG_PDSCH + dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + for(uint16_t idxP=0; idxPmeasurements.rsrp[gNB_index])+ // dB_fixed_times10(RSoffset*12*ue_g[Mod_id][CC_id]->frame_parms.N_RB_DL) + (ue->frame_parms.ss_PBCH_BlockPower*10))/10)); - } + diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 7d383a7aef..96d4462724 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -43,11 +43,20 @@ #include "assertions.h" #include "T.h" -#define DEBUG_DCI_DECODING 1 +//#define DEBUG_DCI_DECODING 1 //#define NR_LTE_PDCCH_DCI_SWITCH #define NR_PDCCH_DCI_RUN // activates new nr functions -#define NR_PDCCH_DCI_DEBUG // activates NR_PDCCH_DCI_DEBUG logs +//#define NR_PDCCH_DCI_DEBUG // activates NR_PDCCH_DCI_DEBUG logs +#ifdef NR_PDCCH_DCI_DEBUG +#define LOG_DNL(a, ...) printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#define LOG_DD(a, ...) printf("\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#define LOG_DDD(a, ...) printf("\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#else +#define LOG_DNL(a...) +#define LOG_DD(a...) +#define LOG_DDD(a...) +#endif #define NR_NBR_CORESET_ACT_BWP 3 // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0) #define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0) @@ -131,24 +140,18 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, if (coreset_interleaved==0) f_bundle_j=bundle_j; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j); -#endif + LOG_DNL("[r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j); } f_reg = (f_bundle_j*reg_bundle_size_L)+(reg%reg_bundle_size_L); - //index_z = 9*reg; - index_z = 9*(uint16_t)floor(reg/coreset_time_dur) + (9*coreset_nbr_rb)*(reg%coreset_time_dur); - //index_llr = 9*(((uint16_t)floor(f_reg/reg_bundle_size_L)+(f_reg)%coreset_time_dur))*(coreset_nbr_rb); + index_z = 9*reg; index_llr = 9*((uint16_t)floor(f_reg/coreset_time_dur)+((f_reg%coreset_time_dur)*(coreset_nbr_rb))); for (int i=0; i<9; i++) { z[index_z + i] = llr[index_llr + i]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", + LOG_DDD("[reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", reg,bundle_j,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]), f_reg,f_bundle_j,(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i])); -#endif } if ((reg%reg_bundle_size_L) == 0) r++; @@ -166,13 +169,11 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, pdcch_llrp = &pdcch_llr[2 * symbol * coreset_nbr_rb * 9]; if (!pdcch_llrp) { - printf("pdcch_qpsk_llr: llr is null, symbol %d\n", symbol); + LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n", symbol); return (-1); } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llrp-pdcch_llr); -#endif + LOG_DDD("llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %ld\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llrp-pdcch_llr); //for (i = 0; i < (frame_parms->N_RB_DL * ((symbol == 0) ? 16 : 24)); i++) { for (i = 0; i < (coreset_nbr_rb * ((symbol == 0) ? 18 : 18)); i++) { @@ -183,9 +184,7 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, else *pdcch_llrp = (*rxF); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: rb=%d i=%d *rxF:%d => *pdcch_llrp:%d\n",i/18,i,*rxF,*pdcch_llrp); -#endif + LOG_DDD("llr logs: rb=%d i=%d *rxF:%d => *pdcch_llrp:%d\n",i/18,i,*rxF,*pdcch_llrp); rxF++; pdcch_llrp++; } @@ -206,7 +205,7 @@ int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12]; if (!pdcch_llr8) { - printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); + LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); return(-1); } @@ -301,9 +300,8 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, uint8_t symbol, - uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, - uint64_t coreset_freq_dom, + uint8_t *coreset_freq_dom, uint32_t coreset_nbr_rb, uint32_t n_BWP_start) { /* @@ -329,43 +327,23 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //uint8_t rb_count_bit; uint8_t i, j, aarx, bitcnt_coreset_freq_dom=0; int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext; -#ifdef NR_PDCCH_DCI_DEBUG - int nushiftmod3 = frame_parms->nushift % 3; -#endif -#if defined(DEBUG_DCI_DECODING) || defined(NR_PDCCH_DCI_DEBUG) - uint8_t symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol; -#endif - c_rb = n_BWP_start; // c_rb is the common resource block: RB within the BWP #ifdef DEBUG_DCI_DECODING + uint8_t symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol; LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod); #endif for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - if (high_speed_flag == 1) { - dl_ch0 = &dl_ch_estimates[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][ (symbol * (frame_parms->ofdm_symbol_size (%d))) = (%d)]\n", - aarx,frame_parms->ofdm_symbol_size,(symbol * (frame_parms->ofdm_symbol_size))); -#endif - } else { - dl_ch0 = &dl_ch_estimates[aarx][0]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx); -#endif - } + dl_ch0 = &dl_ch_estimates[aarx][0]; + LOG_DDD("dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx); dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", + LOG_DDD("dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)); -#endif rxF_ext = &rxdataF_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", + LOG_DDD("rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> (for symbol=%d, aarx=%d), symbol_mod=%d, nushiftmod3=%d \n",symbol,aarx,symbol_mod,nushiftmod3); -#endif + /* * The following for loop handles treatment of PDCCH contained in table rxdataF (in frequency domain) * In NR the PDCCH IQ symbols are contained within RBs in the CORESET defined by higher layers which is located within the BWP @@ -383,55 +361,34 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, * then the IQ symbol is going to be found at the position 0+c_rb-N_RB_DL/2 in rxdataF and * we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF */ -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb); -#endif + LOG_DDD("n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb); + int c_rb_by6; + c_rb = n_BWP_start; + for (int rb=0;rb>3] & (1<<(c_rb_by6&7))) == 0) c_rb+=6; - for (c_rb = n_BWP_start; c_rb < (n_BWP_start + coreset_nbr_rb + (BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN * offset_discontiguous)); c_rb++) { - //c_rb_tmp = 0; - if (((c_rb - n_BWP_start) % BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN)==0) { - bitcnt_coreset_freq_dom ++; - - while ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (CORESET_FREQ_DOMAIN_BITMAP_SIZE - bitcnt_coreset_freq_dom)) & 0x1)== 0) { // 46 -> 45 is number of bits in coreset_freq_dom - // next 6 RB are not part of the CORESET within the BWP as bit in coreset_freq_dom is set to 0 - bitcnt_coreset_freq_dom ++; - //c_rb_tmp = c_rb_tmp + 6; - c_rb = c_rb + BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN; - offset_discontiguous ++; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> we entered here as coreset_freq_dom=%lx (bit %d) is 0, coreset_freq_domain is discontiguous\n",coreset_freq_dom, - (46 - bitcnt_coreset_freq_dom)); -#endif - } - } - - //c_rb = c_rb + c_rb_tmp; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> c_rb=%d\n",c_rb); -#endif + LOG_DDD("c_rb=%d\n",c_rb); rxF=NULL; // first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start) if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif } if ((c_rb >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC) // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif //rxF = &rxdataF[aarx][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol //#ifdef NR_PDCCH_DCI_DEBUG - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + // LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", // c_rb,aarx,(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))); //#endif } @@ -440,7 +397,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); #endif } @@ -450,7 +407,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))); #endif } @@ -460,30 +417,9 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table) rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); #endif - /*if (symbol_mod > 300) { // this if is going to be removed as DM-RS signals are present in all symbols of PDCCH - for (i = 0; i < 6; i++) { - dl_ch0_ext[i] = dl_ch0[i]; - rxF_ext[i] = rxF[i]; - } - rxF = &rxdataF[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; // we point at the 1st part of the rxdataF in symbol - #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", - c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size))); - #endif - for (; i < 12; i++) { - dl_ch0_ext[i] = dl_ch0[i]; - rxF_ext[i] = rxF[(1 + i - 6)]; - } - nb_rb++; - dl_ch0_ext += 12; - rxF_ext += 12; - dl_ch0 += 12; - rxF += 7; - c_rb++; - } else {*/ j = 0; for (i = 0; i < 6; i++) { //treating first part of the RB note that i=5 would correspond to DC. We treat it in NR @@ -497,10 +433,9 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // then we point at the begining of the symbol part of rxdataF do process second part of RB rxF = &rxdataF[aarx][((symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", + LOG_D(PHY,"in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size))); #endif - for (; i < 12; i++) { if ((i != 9)) { dl_ch0_ext[j] = dl_ch0[i]; @@ -518,34 +453,24 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //n_BWP_start++; // We have to increment this variable here to be consequent in the for loop afterwards //} } else { // treatment of any RB that does not contain the DC - /*if (symbol_mod > 300) { - memcpy(dl_ch0_ext, dl_ch0, 12 * sizeof(int32_t)); - for (i = 0; i < 12; i++) { - rxF_ext[i] = rxF[i]; - } - nb_rb++; - dl_ch0_ext += 12; - rxF_ext += 12; - dl_ch0 += 12; - //rxF += 12; - } else {*/ j = 0; for (i = 0; i < 12; i++) { if ((i != 1) && (i != 5) && (i != 9)) { rxF_ext[j] = rxF[i]; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n", + LOG_D(PHY,"RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n", c_rb, i, j, *(short *) &rxF_ext[j],*(1 + (short *) &rxF_ext[j]), i, *(short *) &rxF[i], *(1 + (short *) &rxF[i])); #endif dl_ch0_ext[j] = dl_ch0[i]; - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); + + //LOG_DDD("ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); //printf("\t-> dl_ch0[%d] => dl_ch0_ext[%d](%d,%d)\n", i,j, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); j++; } else { #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n", + LOG_D(PHY,"RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n", c_rb, i, j, *(short *) &rxF_ext[j], *(1 + (short *) &rxF_ext[j]), i, *(short *) &rxF[i], *(1 + (short *) &rxF[i])); #endif @@ -657,15 +582,13 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext, //print_shorts("rx:",rxdataF128+2); //print_shorts("ch:",dl_ch128+2); //print_shorts("pack:",rxdataF_comp128+2); -#ifdef NR_PDCCH_DCI_DEBUG for (int i=0; i<12 ; i++) - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n", + LOG_DDD("rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n", (rb*12)+i, ((short *)rxdataF128)[i<<1],((short *)rxdataF128)[1+(i<<1)], (rb*12)+i, ((short *)dl_ch128)[i<<1],((short *)dl_ch128)[1+(i<<1)], (rb*12)+i, ((short *)rxdataF_comp128)[i<<1],((short *)rxdataF_comp128)[1+(i<<1)]); -#endif dl_ch128+=3; rxdataF128+=3; rxdataF_comp128+=3; @@ -738,6 +661,116 @@ void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms, #ifdef NR_PDCCH_DCI_RUN +int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, + uint32_t frame, + uint32_t slot) { + + NR_UE_COMMON *common_vars = &ue->common_vars; + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[slot]][0]; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + + uint8_t log2_maxh, aarx; + int32_t avgs; + int32_t avgP[4]; + for (int i=0;inb_search_space;i++) { + + rel15 = &pdcch_vars->pdcch_config[i]; + int n_rb,rb_offset; + get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset); + for (int s=rel15->coreset.StartSymbolIndex; + s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); + s++) { + + nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[slot]].rxdataF, + pdcch_vars->dl_ch_estimates, + pdcch_vars->rxdataF_ext, + pdcch_vars->dl_ch_estimates_ext, + s, + frame_parms, + rel15->coreset.frequency_domain_resource, + n_rb, + rel15->BWPStart); + + LOG_DD("we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP); + LOG_DD("in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); + // compute channel level based on ofdm symbol 0 + pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext, + frame_parms, + avgP, + n_rb); + avgs = 0; + + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) + avgs = cmax(avgs, avgP[aarx]); + + log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx; +#ifdef UE_DEBUG_TRACE + LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs); +#endif +#if T_TRACER + T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(frame%1024), T_INT(slot), + T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); +#endif + LOG_DD("we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); + LOG_DD("in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); + // compute LLRs for ofdm symbol 0 only + nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext, + pdcch_vars->dl_ch_estimates_ext, + pdcch_vars->rxdataF_comp, + NULL, + frame_parms, + s, + log2_maxh, + n_rb); // log2_maxh+I0_shift + if (frame_parms->nb_antennas_rx > 1) { + LOG_DD("we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", + frame_parms->nb_antennas_rx); + pdcch_detection_mrc(frame_parms, pdcch_vars->rxdataF_comp,s); + } + + LOG_DD("we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); + LOG_DD("in nr_pdcch_llr(rxdataF_comp -> llr)\n"); + nr_pdcch_llr(frame_parms, + pdcch_vars->rxdataF_comp, + pdcch_vars->llr, + s, + n_rb); +#if T_TRACER + + // T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), + // T_INT(n_pdcch_symbols), + // T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); + +#endif +#ifdef DEBUG_DCI_DECODING + printf("demapping: slot %d, mi %d\n",slot,get_mi(frame_parms,slot)); +#endif + } + + LOG_DD("we enter nr_pdcch_demapping_deinterleaving()\n"); + nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr, + (uint32_t *) pdcch_vars->e_rx, + frame_parms, + rel15->coreset.duration, + n_rb, + rel15->coreset.RegBundleSize, + rel15->coreset.InterleaverSize, + rel15->coreset.ShiftIndex); + nr_pdcch_unscrambling(rel15->rnti, + frame_parms, + slot, + pdcch_vars->e_rx, + rel15->coreset.duration*n_rb*9*2, + // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72, + rel15->coreset.pdcch_dmrs_scrambling_id); + LOG_DD("we end nr_pdcch_unscrambling()\n"); + LOG_DD("Ending nr_rx_pdcch() function\n"); + return (0); + } + +} + /* int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, uint32_t frame, uint8_t nr_tti_rx, @@ -780,7 +813,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // For each BWP the number of CORESETs is limited to 3 (including initial CORESET Id=0 -> ControlResourceSetId (0..maxNrofControlReourceSets-1) (0..12-1) //uint32_t n_BWP_start = 0; //uint32_t n_rb_offset = 0; - uint32_t n_rb_offset = pdcch_vars2->coreset[nb_coreset_active].rb_offset;/*+(int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB);*/ + uint32_t n_rb_offset = pdcch_vars2->coreset[nb_coreset_active].rb_offset;//+(int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB); // start time position for CORESET // parameter symbol_mon is a 14 bits bitmap indicating monitoring symbols within a slot uint8_t start_symbol = 0; @@ -794,11 +827,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", + LOG_DD("symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol); + LOG_DD("coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", coreset_freq_dom,n_rb_offset,coreset_time_dur,n_shift,reg_bundle_size_L,coreset_interleaver_size_R,pdcch_DMRS_scrambling_id); -#endif // // according to 38.213 v15.1.0: a PDCCH monitoring pattern within a slot, // indicating first symbol(s) of the control resource set within a slot @@ -814,9 +845,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // for (int j=0; j < coreset_nbr_act; j++) { // for each active CORESET (max number of active CORESETs in a BWP is 3), // we calculate the number of RB for each CORESET bitmap -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld)\n",coreset_freq_dom); -#endif + LOG_DD("coreset_freq_dom=(%ld)\n",coreset_freq_dom); int i; //for each bit in the coreset_freq_dom bitmap for (i = 0; i < 45; i++) { @@ -825,22 +854,18 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } coreset_nbr_rb = 6 * coreset_nbr_rb; // coreset_nbr_rb has to be multiplied by 6 to indicate the number of PRB or REG(=12 RE) within the CORESET -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - uint8_t coreset_nbr_reg = coreset_time_dur * coreset_nbr_rb; - uint32_t coreset_C = (uint32_t)(coreset_nbr_reg / (reg_bundle_size_L * coreset_interleaver_size_R)); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n", - coreset_nbr_rb, coreset_nbr_reg, coreset_nbr_reg, reg_bundle_size_L,coreset_interleaver_size_R, coreset_C); -#endif + LOG_DD("coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); + LOG_DD("coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n", + coreset_nbr_rb, + coreset_time_dur * coreset_nbr_rb, + coreset_time_dur * coreset_nbr_rb, + reg_bundle_size_L,coreset_interleaver_size_R, + (uint32_t)((coreset_time_dur * coreset_nbr_rb) / (reg_bundle_size_L * coreset_interleaver_size_R)) ); for (int s = start_symbol; s < (start_symbol + coreset_time_dur); s++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n", + LOG_DD("we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n", is_secondary_ue); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); -#endif + LOG_DD("in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, pdcch_vars[eNB_id]->dl_ch_estimates, pdcch_vars[eNB_id]->rxdataF_ext, @@ -851,10 +876,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, coreset_freq_dom, coreset_nbr_rb, n_rb_offset); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",avgP); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); -#endif + LOG_DD("we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP); + LOG_DD("in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); // compute channel level based on ofdm symbol 0 pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, @@ -873,10 +896,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx), T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); #endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); -#endif + LOG_DD("we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); + LOG_DD("in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); // compute LLRs for ofdm symbol 0 only nr_pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext, pdcch_vars[eNB_id]->dl_ch_estimates_ext, @@ -894,37 +915,31 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif if (frame_parms->nb_antennas_rx > 1) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", + LOG_DD("we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx); -#endif pdcch_detection_mrc(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s); } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_llr(rxdataF_comp -> llr)\n"); -#endif + LOG_DD("we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); + LOG_DD("in nr_pdcch_llr(rxdataF_comp -> llr)\n"); nr_pdcch_llr(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp, pdcch_vars[eNB_id]->llr, s, coreset_nbr_rb); #if T_TRACER - /* - T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), - T_INT(n_pdcch_symbols), - T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); - */ + + // T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), + // T_INT(n_pdcch_symbols), + // T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); + #endif #ifdef DEBUG_DCI_DECODING printf("demapping: nr_tti_rx %d, mi %d\n",nr_tti_rx,get_mi(frame_parms,nr_tti_rx)); #endif } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_demapping_deinterleaving()\n"); -#endif + LOG_DD("we enter nr_pdcch_demapping_deinterleaving()\n"); nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars[eNB_id]->llr, (uint32_t *) pdcch_vars[eNB_id]->e_rx, frame_parms, @@ -941,14 +956,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72, pdcch_DMRS_scrambling_id, do_common); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we end nr_pdcch_unscrambling()\n"); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> Ending nr_rx_pdcch() function\n"); -#endif + LOG_DD("we end nr_pdcch_unscrambling()\n"); + LOG_DD("Ending nr_rx_pdcch() function\n"); return (0); } + */ #endif @@ -980,70 +992,28 @@ void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, #ifdef NR_PDCCH_DCI_RUN -void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t nr_tti_rx, - int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id, int do_common) { +void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot, + int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id) { int i; uint8_t reset; uint32_t x1, x2, s = 0; uint16_t n_id; //{0,1,...,65535} uint32_t n_rnti; reset = 1; - // x1 is set in first call to lte_gold_generic //do_common=1; - if (do_common) { - n_id = frame_parms->Nid_cell; - n_rnti = 0; - } else { n_id = pdcch_DMRS_scrambling_id; n_rnti = (uint32_t)crnti; - } - //x2 = ((n_rnti * (1 << 16)) + n_id)%(1 << 31); - //uint32_t puissance_2_16 = ((1<<16)*n_rnti)+n_id; - //uint32_t puissance_2_31= (1<<30)*2; - //uint32_t calc_x2=puissance_2_16%puissance_2_31; x2 = (((1<<16)*n_rnti)+n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3 - // x2 = (nr_tti_rx << 9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 -#ifdef NR_PDCCH_DCI_DEBUG - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> (c_init=%d, n_id=%d, n_rnti=%d, length=%d)\n",x2,n_id,n_rnti,length); -#endif for (i = 0; i < length; i++) { if ((i & 0x1f) == 0) { s = lte_gold_generic(&x1, &x2, reset); - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> lte_gold[%d]=%x\n",i,s); reset = 0; } - /* - #ifdef NR_PDCCH_DCI_DEBUG - if (i%2 == 0) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", - i,*(char*) &z[(int)floor(i/2)]); - if (i%2 == 1) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", - i,*(1 + (char*) &z[(int)floor(i/2)])); - #endif - if (((s >> (i % 32)) & 1) == 1){ - if (i%2 == 0) *(char*) &z[(int)floor(i/2)] = -(*(char*) &z[(int)floor(i/2)]); - if (i%2 == 1) *(1 + (char*) &z[(int)floor(i/2)]) = -(*(1 + (char*) &z[(int)floor(i/2)])); - } - //llr[i] = -llr[i]; - //llr[i] = (-1)*llr[i]; - #ifdef NR_PDCCH_DCI_DEBUG - if (i%2 == 0) printf("unscrambled_z=%d\n",*(char*) &z[(int)floor(i/2)]); - if (i%2 == 1) printf("unscrambled_z=%d\n",*(1 + (char*) &z[(int)floor(i/2)])); - #endif - */ -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", - i,z[i]); -#endif - if (((s >> (i % 32)) & 1) == 1) z[i] = -z[i]; - -#ifdef NR_PDCCH_DCI_DEBUG - printf("unscrambled_z=%d\n",z[i]); -#endif } } @@ -1051,6 +1021,42 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 #ifdef NR_PDCCH_DCI_RUN +uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, + int frame, + int slot, + fapi_nr_dci_indication_t *dci_ind) { + + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[slot]][0]; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + for (int i=0;inb_search_space;i++) { + + rel15 = &pdcch_vars->pdcch_config[i]; + int dci_length = rel15->dci_length; + for (int j=0;jnumber_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(1, dci_length, L,1,&ue->polarList); + uint16_t crc = polar_decoder_int16(&pdcch_vars->e_rx[CCEind*9*6*2], + dci_estimation, + 1, + currentPtrDCI); + if (crc == rel15->rnti) { + dci_ind->SFN = frame; + dci_ind->slot = slot; + dci_ind->dci_list[dci_ind->number_of_dcis].rnti = rel15->rnti; + dci_ind->dci_list[dci_ind->number_of_dcis].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++; + } + } + } + return(dci_ind->number_of_dcis); +} + +/* void nr_dci_decoding_procedure0(int s, int p, int coreset_time_dur, @@ -1089,19 +1095,15 @@ void nr_dci_decoding_procedure0(int s, //Table 10.1-3: Maximum number of non-overlapped CCEs per slot and per serving cell as a function of the subcarrier spacing value 2^mu*15 KHz, mu {0,1,2,3} //uint8_t cce_max_slot_pdcch_Table10_1_3 [4] = {56,56,48,32}; int coreset_nbr_cce_per_symbol=0; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found is %d \n", *format_found); -#endif + LOG_DDD("format_found is %d \n", *format_found); //if (mode == NO_DCI) { // #ifdef NR_PDCCH_DCI_DEBUG - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx); + // LOG_DDD("skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx); // #endif // return; //} -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> frequencyDomainResources=%lx, duration=%d\n", + LOG_DDD("frequencyDomainResources=%lx, duration=%d\n", pdcch_vars[eNB_id]->coreset[p].frequencyDomainResources, pdcch_vars[eNB_id]->coreset[p].duration); -#endif // nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols, frame_parms, mi); for (int i = 0; i < 45; i++) { @@ -1115,28 +1117,26 @@ void nr_dci_decoding_procedure0(int s, // the number of symbols in the CORESET (pdcch_vars[eNB_id]->coreset[p].duration) // multiplied by the number of bits set to '1' in the frequencyDomainResources bitmap // (1 bit set to '1' corresponds to 6 RB and 1 CCE = 6 RB) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> nCCE[%d]=%d\n",p,nCCE[p]); -#endif + LOG_DDD("nCCE[%d]=%d\n",p,nCCE[p]); - /* if (nCCE > get_nCCE(3, frame_parms, 1)) { - LOG_D(PHY, - "skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", - nCCE, get_nCCE(3, frame_parms, 1)); - return; - } + // if (nCCE > get_nCCE(3, frame_parms, 1)) { + //LOG_D(PHY, + //"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", + //nCCE, get_nCCE(3, frame_parms, 1)); + //return; + // } - if (nCCE < L2) { - LOG_D(PHY, "skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2); - return; - } +// if (nCCE < L2) { +// LOG_D(PHY, "skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2); +// return; +// } + +// if (mode == NO_DCI) { +// LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n", +// nr_tti_rx); +// return; +// } - if (mode == NO_DCI) { - LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n", - nr_tti_rx); - return; - } - */ if (do_common == 1) { Yk = 0; @@ -1171,9 +1171,7 @@ void nr_dci_decoding_procedure0(int s, nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.srs_nrofCandidates; } else { nb_candidates = (L2 == 4) ? 4 : ((L2 == 8)? 2 : 1); // according to Table 10.1-1 (38.213 section 10.1) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> we are in common searchSpace and nb_candidates=%d for L2=%d\n",nb_candidates,L2); -#endif + LOG_DDD("we are in common searchSpace and nb_candidates=%u for L2=%d\n", nb_candidates, L2); } } else { switch (L2) { @@ -1210,12 +1208,10 @@ void nr_dci_decoding_procedure0(int s, Yk = (Yk * A[p%3]) % 65537; } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> L2(%d) | nCCE[%d](%d) | Yk(%d) | nb_candidates(%d)\n",L2,p,nCCE[p],Yk,nb_candidates); -#endif - /* for (CCEind=0; - CCEind nCCE[p]) // nb_candidates = nCCE[p] / L2; // In the next code line there is maybe a bug. The spec is not comparing Table 10.1-2 with nb_candidates, but with total number of candidates for all s and all p @@ -1223,27 +1219,19 @@ void nr_dci_decoding_procedure0(int s, if (L==4) m_p_s_L_max=1; // Table 10.1-2 is not defined for L=4 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]); -#endif + if(0 <= L && L < 4) LOG_DDD("m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]); for (m = 0; m < nb_candidates; m++) { int n_ci = 0; if (nCCE[p] < L2) return; -#ifdef NR_PDCCH_DCI_DEBUG - int debug1 = nCCE[p] / L2; - int debug2 = L2*m_p_s_L_max; - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",debug1,p,nCCE[p],L2); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",debug2,L2,m_p_s_L_max); -#endif - CCEind = (((Yk + (uint16_t)(floor((m*nCCE[p])/(L2*m_p_s_L_max))) + n_ci) % (uint16_t)(floor(nCCE[p] / L2))) * L2); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEind(%d) = (((Yk(%d) + ((m(%d)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) % (nCCE[p] / L2)) * L2)\n", + LOG_DDD("debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",nCCE[p] / L2,p,nCCE[p],L2); + LOG_DDD("debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",L2*m_p_s_L_max,L2,m_p_s_L_max); + CCEind = (((Yk + (uint16_t)(floor((m*nCCE[p])/(L2*m_p_s_L_max))) + n_ci) % (uint16_t)(floor(nCCE[p] / L2))) * L2); + LOG_DDD("CCEind(%d) = (((Yk(%u) + ((m(%u)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) %% (nCCE[p] / L2)) * L2)\n", CCEind,Yk,m,nCCE[p],L2,m_p_s_L_max); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> n_candidate(m)=%d | CCEind=%d |",m,CCEind); -#endif + LOG_DDD("n_candidate(m)=%u | CCEind=%d |",m,CCEind); if (CCEind < 32) CCEmap = CCEmap0; @@ -1251,7 +1239,7 @@ void nr_dci_decoding_procedure0(int s, CCEmap = CCEmap1; else if (CCEind < 96) CCEmap = CCEmap2; - else AssertFatal(1==0,"Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind, Yk, m, nCCE[p], L2); + else AssertFatal(1==0,"Illegal CCEind %d (Yk %u, m %u, nCCE %d, L2 %d\n", CCEind, Yk, m, nCCE[p], L2); switch (L2) { case 1: @@ -1282,9 +1270,7 @@ void nr_dci_decoding_procedure0(int s, CCEmap_cand = (*CCEmap) & CCEmap_mask; // CCE is not allocated yet -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEmap_cand=%d \n",CCEmap_cand); -#endif + LOG_DDD("CCEmap_cand=%u \n",CCEmap_cand); if (CCEmap_cand == 0) { #ifdef DEBUG_DCI_DECODING @@ -1297,60 +1283,53 @@ void nr_dci_decoding_procedure0(int s, pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_uss); #endif -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n"); -#endif + LOG_DDD("... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L); + LOG_DDD("... we have to replace this part of the code by polar decoding\n"); // for (int m=0; m < (nCCE[p]*6*9*2); m++) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n", + LOG_DDD("(polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n", coreset_time_dur,coreset_nbr_rb,p,CCEind); -#endif - /* - int reg_p=0,reg_e=0; - for (int m=0; m < (L2*6); m++){ - reg_p = (((int)floor(m/coreset_time_dur))+((m%coreset_time_dur)*(L2*6/coreset_time_dur)))*9*2; - reg_e = m*9*2; - for (int i=0; i<9*2; i++){ + + //int reg_p=0,reg_e=0; + //for (int m=0; m < (L2*6); m++){ + //reg_p = (((int)floor(m/coreset_time_dur))+((m%coreset_time_dur)*(L2*6/coreset_time_dur)))*9*2; + //reg_e = m*9*2; + //for (int i=0; i<9*2; i++){ //polar_input[reg_p+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1.0):(-1.0); - polar_input[reg_e+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1/sqrt(2)):((-1)/sqrt(2)); + //polar_input[reg_e+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1/sqrt(2)):((-1)/sqrt(2)); //printf("\t m=%d \tpolar_input[%d]=%lf <-> e_rx[%d]=%d\n",m,reg_e+i,polar_input[reg_e+i], // ((CCEind*9*6*2) + reg_e + i),pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]); //printf("\t m=%d \tpolar_input[%d]=%lf <-> e_rx[%d]=%d\n",m,reg_p+i,polar_input[reg_p+i], // ((CCEind*9*6*2) + reg_e + i),pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]); - } - } + //} + //} - #ifdef NR_PDCCH_DCI_DEBUG - printf("\n"); - int j=0; - uint32_t polar_hex[27] = {0}; - for (int i=0; i polar_hex[%d]=%x\n",j,polar_hex[j]); - #endif - */ + //polar_hex[j] = polar_hex[j] + (((polar_input[i]==((-1)/sqrt(2)))?1:0)<<(i%32)); + //} + //for (j=0;j<27;j++) LOG_DDD("polar_hex[%d]=%x\n",j,polar_hex[j]); + //#endif + uint64_t dci_estimation[2]= {0}; - const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, sizeof_bits, L2); + const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, sizeof_bits, L2,1); decoderState = polar_decoder_int16(&pdcch_vars[eNB_id]->e_rx[CCEind*9*6*2], dci_estimation, + 1, currentPtrDCI); crc = decoderState; //crc = (crc16(&dci_decoded_output[current_thread_id][0], sizeof_bits) >> 16) ^ extract_crc(&dci_decoded_output[current_thread_id][0], sizeof_bits); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we end function dci_decoding() with crc=%x\n",crc); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n"); -#endif + LOG_DDD("... we end function dci_decoding() with crc=%x\n",crc); + LOG_DDD("... we have to replace this part of the code by polar decoding\n"); #ifdef DEBUG_DCI_DECODING - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: crc =>%d\n",crc); + LOG_DDD("(nr_dci_decoding_procedure0: crc =>%d\n",crc); #endif //uint16_t tc_rnti, uint16_t int_rnti, uint16_t sfi_rnti, uint16_t tpc_pusch_rnti, uint16_t tpc_pucch_rnti, uint16_t tpc_srs__rnti -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled); -#endif + LOG_DDD("format_found=%d\n",*format_found); + LOG_DDD("crc_scrambled=%d\n",*crc_scrambled); if (crc == crc_scrambled_values[_C_RNTI_]) { *crc_scrambled =_c_rnti; @@ -1418,10 +1397,8 @@ void nr_dci_decoding_procedure0(int s, } -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled); -#endif + LOG_DDD("format_found=%d\n",*format_found); + LOG_DDD("crc_scrambled=%d\n",*crc_scrambled); if (*format_found!=255) { dci_alloc[*dci_cnt].dci_length = sizeof_bits; @@ -1430,31 +1407,29 @@ void nr_dci_decoding_procedure0(int s, dci_alloc[*dci_cnt].firstCCE = CCEind; memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_estimation,8); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n", + LOG_DDD("rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n", dci_alloc[*dci_cnt].rnti, dci_alloc[*dci_cnt].dci_length, sizeof_bytes); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n", + LOG_DDD("dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n", *dci_cnt, format_css,*crc_scrambled,dci_alloc[*dci_cnt].L, dci_alloc[*dci_cnt].firstCCE,dci_alloc[*dci_cnt].dci_pdu[0],dci_alloc[*dci_cnt].dci_pdu[1]); -#endif if ((format_css == cformat0_0_and_1_0) || (format_uss == uformat0_0_and_1_0)) { if ((*crc_scrambled == _p_rnti) || (*crc_scrambled == _si_rnti) || (*crc_scrambled == _ra_rnti)) { dci_alloc[*dci_cnt].format = format1_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_1_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> a format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("a format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } else { if ((dci_estimation[0]&1) == 0) { dci_alloc[*dci_cnt].format = format0_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_0_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> b format0_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("b format0_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } if ((dci_estimation[0]&1) == 1) { dci_alloc[*dci_cnt].format = format1_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_1_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> c format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("c format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } } } @@ -1500,42 +1475,42 @@ void nr_dci_decoding_procedure0(int s, // store first nCCE of group for PUCCH transmission of ACK/NAK pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - /* if (crc == si_rnti) { - dci_alloc[*dci_cnt].format = format_si; - *dci_cnt = *dci_cnt + 1; - } else if (crc == p_rnti) { - dci_alloc[*dci_cnt].format = format_p; - *dci_cnt = *dci_cnt + 1; - } else if (crc == ra_rnti) { - dci_alloc[*dci_cnt].format = format_ra; - // store first nCCE of group for PUCCH transmission of ACK/NAK - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - *dci_cnt = *dci_cnt + 1; - } else if (crc == pdcch_vars[eNB_id]->crnti) { + // if (crc == si_rnti) { + // dci_alloc[*dci_cnt].format = format_si; + // *dci_cnt = *dci_cnt + 1; + // } else if (crc == p_rnti) { + // dci_alloc[*dci_cnt].format = format_p; + // *dci_cnt = *dci_cnt + 1; + // } else if (crc == ra_rnti) { + // dci_alloc[*dci_cnt].format = format_ra; + // // store first nCCE of group for PUCCH transmission of ACK/NAK + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // *dci_cnt = *dci_cnt + 1; + // } else if (crc == pdcch_vars[eNB_id]->crnti) { - if ((mode & UL_DCI) && (format_c == format0) - && ((dci_decoded_output[current_thread_id][0] & 0x80) - == 0)) { // check if pdu is format 0 or 1A - if (*format0_found == 0) { - dci_alloc[*dci_cnt].format = format0; - *format0_found = 1; - *dci_cnt = *dci_cnt + 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - } - } else if (format_c == format0) { // this is a format 1A DCI - dci_alloc[*dci_cnt].format = format1A; - *dci_cnt = *dci_cnt + 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - } else { - // store first nCCE of group for PUCCH transmission of ACK/NAK - if (*format_c_found == 0) { - dci_alloc[*dci_cnt].format = format_c; - *dci_cnt = *dci_cnt + 1; - *format_c_found = 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; - } - } - }*/ + // if ((mode & UL_DCI) && (format_c == format0) + // && ((dci_decoded_output[current_thread_id][0] & 0x80) + // == 0)) { // check if pdu is format 0 or 1A + // if (*format0_found == 0) { + // dci_alloc[*dci_cnt].format = format0; + // *format0_found = 1; + // *dci_cnt = *dci_cnt + 1; + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // } + // } else if (format_c == format0) { // this is a format 1A DCI + // dci_alloc[*dci_cnt].format = format1A; + // *dci_cnt = *dci_cnt + 1; + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // } else { + // // store first nCCE of group for PUCCH transmission of ACK/NAK + // if (*format_c_found == 0) { + // dci_alloc[*dci_cnt].format = format_c; + // *dci_cnt = *dci_cnt + 1; + // *format_c_found = 1; + // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // } + // } + // } //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[nr_tti_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_tti_rx, pdcch_vars[eNB_id]->nCCE[nr_tti_rx],L2); // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); switch (1 << L) { @@ -1572,1057 +1547,30 @@ void nr_dci_decoding_procedure0(int s, printf("\n"); } - /* - if ( agregationLevel != 0xFF && - (format_c == format0 && m==0 && si_rnti != SI_RNTI)) - { - //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0. - return; - } - */ + + // if ( agregationLevel != 0xFF && + // (format_c == format0 && m==0 && si_rnti != SI_RNTI)) + // { + // //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0. + // return; + // } + } // candidate loop -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> end candidate loop\n"); -#endif + LOG_DDD("end candidate loop\n"); } - -#endif - - - - - -/*void dci_decoding_procedure0(NR_UE_PDCCH **pdcch_vars, - int do_common, - dci_detect_mode_t mode, - uint8_t nr_tti_rx, - DCI_ALLOC_t *dci_alloc, - int16_t eNB_id, - uint8_t current_thread_id, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t mi, - uint16_t si_rnti, - uint16_t ra_rnti, - uint16_t p_rnti, - uint8_t L, - uint8_t format_si, - uint8_t format_p, - uint8_t format_ra, - uint8_t format_c, - uint8_t sizeof_bits, - uint8_t sizeof_bytes, - uint8_t *dci_cnt, - uint8_t *format0_found, - uint8_t *format_c_found, - uint32_t *CCEmap0, - uint32_t *CCEmap1, - uint32_t *CCEmap2) - { - - uint16_t crc,CCEind,nCCE; - uint32_t *CCEmap=NULL,CCEmap_mask=0; - int L2=(1< \n"); - #endif - nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi); - - if (nCCE > get_nCCE(3,frame_parms,1)) { - LOG_D(PHY,"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", nCCE, get_nCCE(3,frame_parms,1)); - return; - } - - if (nCCEcrnti; - - for (i=0; i<=nr_tti_rx; i++) - Yk = (Yk*39827)%65537; - - Yk = Yk % (nCCE/L2); - - switch (L2) { - case 1: - case 2: - nb_candidates = 6; - break; - - case 4: - case 8: - nb_candidates = 2; - break; - - default: - DevParam(L2, do_common, eNB_id); - break; - } - } - - // for (CCEind=0; - // CCEind nCCE) - nb_candidates = nCCE/L2; - - for (m=0; mmacphy_exit("Illegal CCEind\n"); - return; // not reached - } - - switch (L2) { - case 1: - CCEmap_mask = (1<<(CCEind&0x1f)); - break; - - case 2: - CCEmap_mask = (3<<(CCEind&0x1f)); - break; - - case 4: - CCEmap_mask = (0xf<<(CCEind&0x1f)); - break; - - case 8: - CCEmap_mask = (0xff<<(CCEind&0x1f)); - break; - - default: - LOG_E( PHY, "Illegal L2 value %d\n", L2 ); - mac_xface->macphy_exit( "Illegal L2\n" ); - return; // not reached - } - - CCEmap_cand = (*CCEmap)&CCEmap_mask; - - // CCE is not allocated yet - - if (CCEmap_cand == 0) { - #ifdef DEBUG_DCI_DECODING - - if (do_common == 1) - LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); - else - LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); - - #endif - - dci_decoding(sizeof_bits, - L, - &pdcch_vars[eNB_id]->e_rx[CCEind*72], - &dci_decoded_output[current_thread_id][0]); - - // for (i=0;i<3+(sizeof_bits>>3);i++) - // printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]); - - crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits); - #ifdef DEBUG_DCI_DECODING - printf("crc =>%x\n",crc); - #endif - - if (((L>1) && ((crc == si_rnti)|| (crc == p_rnti)|| (crc == ra_rnti)))|| - (crc == pdcch_vars[eNB_id]->crnti)) { - dci_alloc[*dci_cnt].dci_length = sizeof_bits; - dci_alloc[*dci_cnt].rnti = crc; - dci_alloc[*dci_cnt].L = L; - dci_alloc[*dci_cnt].firstCCE = CCEind; - - //printf("DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes); - if (sizeof_bytes<=4) { - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3]; - #ifdef DEBUG_DCI_DECODING - printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0], - dci_decoded_output[current_thread_id][1], - dci_decoded_output[current_thread_id][2], - dci_decoded_output[current_thread_id][3]); - #endif - } else { - dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0]; - dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1]; - dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2]; - dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3]; - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7]; - #ifdef DEBUG_DCI_DECODING - printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", - dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3], - dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]); - #endif - } - - if (crc==si_rnti) { - dci_alloc[*dci_cnt].format = format_si; - *dci_cnt = *dci_cnt+1; - } else if (crc==p_rnti) { - dci_alloc[*dci_cnt].format = format_p; - *dci_cnt = *dci_cnt+1; - } else if (crc==ra_rnti) { - dci_alloc[*dci_cnt].format = format_ra; - // store first nCCE of group for PUCCH transmission of ACK/NAK - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - *dci_cnt = *dci_cnt+1; - } else if (crc==pdcch_vars[eNB_id]->crnti) { - - if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A - if (*format0_found == 0) { - dci_alloc[*dci_cnt].format = format0; - *format0_found = 1; - *dci_cnt = *dci_cnt+1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - } - } else if (format_c == format0) { // this is a format 1A DCI - dci_alloc[*dci_cnt].format = format1A; - *dci_cnt = *dci_cnt+1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - } else { - // store first nCCE of group for PUCCH transmission of ACK/NAK - if (*format_c_found == 0) { - dci_alloc[*dci_cnt].format = format_c; - *dci_cnt = *dci_cnt+1; - *format_c_found = 1; - pdcch_vars[eNB_id]->nCCE[nr_tti_rx]=CCEind; - } - } - } - - //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[nr_tti_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_tti_rx, pdcch_vars[eNB_id]->nCCE[nr_tti_rx],L2); - // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); - - - - switch (1<pdcch_vars[ue->current_thread_id[nr_tti_rx]]; - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - uint8_t mi = get_mi(&ue->frame_parms,nr_tti_rx); - uint16_t ra_rnti=99; - uint8_t format0_found=0,format_c_found=0; - uint8_t tmode = ue->transmission_mode[eNB_id]; - uint8_t frame_type = frame_parms->frame_type; - uint8_t format0_size_bits=0,format0_size_bytes=0; - uint8_t format1_size_bits=0,format1_size_bytes=0; - dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,nr_tti_rx); - - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t); - - } else { - format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t); - } - - break; - - case 25: - default: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_5MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_TDD_t); - } else { - format0_size_bits = sizeof_DCI0_5MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_5MHz_FDD_t); - format1_size_bits = sizeof_DCI1_5MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_5MHz_FDD_t); - } - - break; - - case 50: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_10MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_TDD_t); - - } else { - format0_size_bits = sizeof_DCI0_10MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_10MHz_FDD_t); - format1_size_bits = sizeof_DCI1_10MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_10MHz_FDD_t); - } - - break; - - case 100: - if (frame_type == TDD) { - format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; - format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); - format1_size_bits = sizeof_DCI1_20MHz_TDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_TDD_t); - } else { - format0_size_bits = sizeof_DCI0_20MHz_FDD_t; - format0_size_bytes = sizeof(DCI0_20MHz_FDD_t); - format1_size_bits = sizeof_DCI1_20MHz_FDD_t; - format1_size_bytes = sizeof(DCI1_20MHz_FDD_t); - } - - break; - } - - if (ue->prach_resources[eNB_id]) - ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; - - // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8 - dci_decoding_procedure0(pdcch_vars,0,mode, - nr_tti_rx, - dci_alloc, - eNB_id, - ue->current_thread_id[nr_tti_rx], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - agregationLevel, - format1A, - format1A, - format1A, - format0, - format0_size_bits, - format0_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff)|| - ((format0_found==1)&&(format_c_found==1))) - return(dci_cnt); - - if (DCIFormat == 1) - { - if ((tmode < 3) || (tmode == 7)) { - //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); - - // Now check UE_SPEC format 1 search spaces at aggregation 1 - - //printf("[DCI search] Format 1/1A aggregation 1\n"); - - old_dci_cnt=dci_cnt; - dci_decoding_procedure0(pdcch_vars,0,mode,nr_tti_rx, - dci_alloc, - eNB_id, - ue->current_thread_id[nr_tti_rx], - frame_parms, - mi, - ((ue->decode_SIB == 1) ? SI_RNTI : 0), - ra_rnti, - P_RNTI, - 0, - format1A, - format1A, - format1A, - format1, - format1_size_bits, - format1_size_bytes, - &dci_cnt, - &format0_found, - &format_c_found, - &CCEmap0, - &CCEmap1, - &CCEmap2); - - if ((CCEmap0==0xffff) || - (format_c_found==1)) - return(dci_cnt); - - if (dci_cnt>old_dci_cnt) - return(dci_cnt); - - //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat); - - } - else - { - AssertFatal(0,"Other Transmission mode not yet coded\n"); - } - } - else - { - AssertFatal(0,"DCI format %d not yet implemented \n",DCIFormat); - } - - return(dci_cnt); - - } */ - -#ifdef NR_PDCCH_DCI_RUN - -uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, - uint16_t eNB_id, - uint8_t nr_tti_rx, - int p, - crc_scrambled_t crc_scrambled, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint8_t format) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size)-> crc_scrambled=%d, n_RB_ULBWP=%d, n_RB_DLBWP=%d\n",crc_scrambled,n_RB_ULBWP,n_RB_DLBWP); -#endif - /* - * function nr_dci_format_size calculates and returns the size in bits of a determined format - * it also returns an bi-dimensional array 'dci_fields_sizes' with x rows and y columns, where: - * x is the number of fields defined in TS 38.212 subclause 7.3.1 (Each field is mapped in the order in which it appears in the description in the specification) - * y is the number of formats - * e.g.: dci_fields_sizes[10][0] contains the size in bits of the field FREQ_DOM_RESOURCE_ASSIGNMENT_UL for format 0_0 - */ - // pdsch_config contains the PDSCH-Config IE is used to configure the UE specific PDSCH parameters (TS 38.331) - PDSCH_Config_t pdsch_config = ue->PDSCH_Config; - // pusch_config contains the PUSCH-Config IE is used to configure the UE specific PUSCH parameters (TS 38.331) - PUSCH_Config_t pusch_config = ue->pusch_config; - PUCCH_Config_t pucch_config_dedicated = ue->pucch_config_dedicated_nr[eNB_id]; - crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig = ue->crossCarrierSchedulingConfig; - dmrs_UplinkConfig_t dmrs_UplinkConfig = ue->dmrs_UplinkConfig; - dmrs_DownlinkConfig_t dmrs_DownlinkConfig = ue->dmrs_DownlinkConfig; - csi_MeasConfig_t csi_MeasConfig = ue->csi_MeasConfig; - PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig= ue->PUSCH_ServingCellConfig; - PDSCH_ServingCellConfig_t PDSCH_ServingCellConfig= ue->PDSCH_ServingCellConfig; - NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; - // 1 CARRIER_IN - // crossCarrierSchedulingConfig from higher layers, variable crossCarrierSchedulingConfig indicates if 'cross carrier scheduling' is enabled or not: - // if No cross carrier scheduling: number of bits for CARRIER_IND is 0 - // if Cross carrier scheduling: number of bits for CARRIER_IND is 3 - // The IE CrossCarrierSchedulingConfig is used to specify the configuration when the cross-carrier scheduling is used in a cell - uint8_t crossCarrierSchedulingConfig_ind = 0; - - if (crossCarrierSchedulingConfig.schedulingCellInfo.other.cif_InSchedulingCell !=0 ) crossCarrierSchedulingConfig_ind=1; - - // 2 SUL_IND_0_1, // 40 SRS_REQUEST, // 50 SUL_IND_0_0 - // UL/SUL indicator (TS 38.331, supplementary uplink is indicated in higher layer parameter ServCellAdd-SUL from IE ServingCellConfig and ServingCellConfigCommon): - // 0 bit for UEs not configured with SUL in the cell or UEs configured with SUL in the cell but only PUCCH carrier in the cell is configured for PUSCH transmission - // 1 bit for UEs configured with SUL in the cell as defined in Table 7.3.1.1.1-1 - // sul_ind indicates whether SUL is configured in cell or not - uint8_t sul_ind=ue->supplementaryUplink.supplementaryUplink; // this value will be 0 or 1 depending on higher layer parameter ServCellAdd-SUL. FIXME!!! - // 7 BANDWIDTH_PART_IND - // number of UL BWPs configured by higher layers - uint8_t n_UL_BWP_RRC=1; // initialized to 1 but it has to be initialized by higher layers FIXME!!! - n_UL_BWP_RRC = ((n_UL_BWP_RRC > 3)?n_UL_BWP_RRC:(n_UL_BWP_RRC+1)); - // number of DL BWPs configured by higher layers - uint8_t n_DL_BWP_RRC=1; // initialized to 1 but it has to be initialized by higher layers FIXME!!! - n_DL_BWP_RRC = ((n_DL_BWP_RRC > 3)?n_DL_BWP_RRC:(n_DL_BWP_RRC+1)); - // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL - // if format0_0, only resource allocation type 1 is allowed - // if format0_1, then resource allocation type 0 can be configured and N_RBG is defined in TS 38.214 subclause 6.1.2.2.1 - // for PUSCH hopping with resource allocation type 1 - // n_UL_hopping = 1 if the higher layer parameter frequencyHoppingOffsetLists contains two offset values - // n_UL_hopping = 2 if the higher layer parameter frequencyHoppingOffsetLists contains four offset values - uint8_t n_UL_hopping=pusch_config.n_frequencyHoppingOffsetLists; - - if (n_UL_hopping == 2) { - n_UL_hopping = 1; - } else if (n_UL_hopping == 4) { - n_UL_hopping = 2; - } else { - n_UL_hopping = 0; - } - - ul_resourceAllocation_t ul_resource_allocation_type = pusch_config.ul_resourceAllocation; - uint8_t ul_res_alloc_type_0 = 0; - uint8_t ul_res_alloc_type_1 = 0; - - if (ul_resource_allocation_type == ul_resourceAllocationType0) ul_res_alloc_type_0 = 1; - - if (ul_resource_allocation_type == ul_resourceAllocationType1) ul_res_alloc_type_1 = 1; - - if (ul_resource_allocation_type == ul_dynamicSwitch) { - ul_res_alloc_type_0 = 1; - ul_res_alloc_type_1 = 1; - } - - uint8_t n_bits_freq_dom_res_assign_ul=0,n_ul_RGB_tmp; - - if (ul_res_alloc_type_0 == 1) { // implementation of Table 6.1.2.2.1-1 TC 38.214 subclause 6.1.2.2.1 - // config1: PUSCH-Config IE contains rbg-Size ENUMERATED {config1 config2} - ul_rgb_Size_t config = pusch_config.ul_rgbSize; - uint8_t nominal_RBG_P = (config==ul_rgb_config1?2:4); - - if (n_RB_ULBWP > 36) nominal_RBG_P = (config==ul_rgb_config1?4:8); - - if (n_RB_ULBWP > 72) nominal_RBG_P = (config==ul_rgb_config1?8:16); - - if (n_RB_ULBWP > 144) nominal_RBG_P = 16; - - n_bits_freq_dom_res_assign_ul = (uint8_t)ceil((n_RB_ULBWP+(0%nominal_RBG_P))/nominal_RBG_P); //FIXME!!! what is 0??? - n_ul_RGB_tmp = n_bits_freq_dom_res_assign_ul; - } - - if (ul_res_alloc_type_1 == 1) n_bits_freq_dom_res_assign_ul = (uint8_t)(ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)))-n_UL_hopping; - - if ((ul_res_alloc_type_0 == 1) && (ul_res_alloc_type_1 == 1)) - n_bits_freq_dom_res_assign_ul = ((n_bits_freq_dom_res_assign_ul>n_ul_RGB_tmp)?(n_bits_freq_dom_res_assign_ul+1):(n_ul_RGB_tmp+1)); - - // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL - // if format1_0, only resource allocation type 1 is allowed - // if format1_1, then resource allocation type 0 can be configured and N_RBG is defined in TS 38.214 subclause 5.1.2.2.1 - dl_resourceAllocation_t dl_resource_allocation_type = pdsch_config.dl_resourceAllocation; - uint8_t dl_res_alloc_type_0 = 0; - uint8_t dl_res_alloc_type_1 = 0; - - if (dl_resource_allocation_type == dl_resourceAllocationType0) dl_res_alloc_type_0 = 1; - - if (dl_resource_allocation_type == dl_resourceAllocationType1) dl_res_alloc_type_1 = 1; - - if (dl_resource_allocation_type == dl_dynamicSwitch) { - dl_res_alloc_type_0 = 1; - dl_res_alloc_type_1 = 1; - } - - uint8_t n_bits_freq_dom_res_assign_dl=0,n_dl_RGB_tmp; - - if (dl_res_alloc_type_0 == 1) { // implementation of Table 5.1.2.2.1-1 TC 38.214 subclause 6.1.2.2.1 - // config1: PDSCH-Config IE contains rbg-Size ENUMERATED {config1, config2} - dl_rgb_Size_t config = pdsch_config.dl_rgbSize; - uint8_t nominal_RBG_P = (config==dl_rgb_config1?2:4); - - if (n_RB_DLBWP > 36) nominal_RBG_P = (config==dl_rgb_config1?4:8); - - if (n_RB_DLBWP > 72) nominal_RBG_P = (config==dl_rgb_config1?8:16); - - if (n_RB_DLBWP > 144) nominal_RBG_P = 16; - - n_bits_freq_dom_res_assign_dl = (uint8_t)ceil((n_RB_DLBWP+(0%nominal_RBG_P))/nominal_RBG_P); //FIXME!!! what is 0??? - n_dl_RGB_tmp = n_bits_freq_dom_res_assign_dl; - } - - if (dl_res_alloc_type_1 == 1) n_bits_freq_dom_res_assign_dl = (uint8_t)(ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2))); - - if ((dl_res_alloc_type_0 == 1) && (dl_res_alloc_type_1 == 1)) - n_bits_freq_dom_res_assign_dl = ((n_bits_freq_dom_res_assign_dl>n_dl_RGB_tmp)?(n_bits_freq_dom_res_assign_dl+1):(n_dl_RGB_tmp+1)); - - // 12 TIME_DOM_RESOURCE_ASSIGNMENT - uint8_t pusch_alloc_list = pusch_config.n_push_alloc_list; - uint8_t pdsch_alloc_list = pdsch_config.n_pdsh_alloc_list; - // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - static_bundleSize_t static_prb_BundlingType = pdsch_config.prbBundleType.staticBundling; - bundleSizeSet1_t dynamic_prb_BundlingType1 = pdsch_config.prbBundleType.dynamicBundlig.bundleSizeSet1; - bundleSizeSet2_t dynamic_prb_BundlingType2 = pdsch_config.prbBundleType.dynamicBundlig.bundleSizeSet2; - uint8_t prb_BundlingType_size=0; - - if ((static_prb_BundlingType==st_n4)||(static_prb_BundlingType==st_wideband)) prb_BundlingType_size=0; - - if ((dynamic_prb_BundlingType1==dy_1_n4)||(dynamic_prb_BundlingType1==dy_1_wideband)||(dynamic_prb_BundlingType1==dy_1_n2_wideband)||(dynamic_prb_BundlingType1==dy_1_n4_wideband)|| - (dynamic_prb_BundlingType2==dy_2_n4)||(dynamic_prb_BundlingType2==dy_2_wideband)) prb_BundlingType_size=1; - - // 15 RATE_MATCHING_IND FIXME!!! - // according to TS 38.212: Rate matching indicator – 0, 1, or 2 bits according to higher layer parameter rateMatchPattern - uint8_t rateMatching_bits = pdsch_config.n_rateMatchPatterns; - // 16 ZP_CSI_RS_TRIGGER FIXME!!! - // 0, 1, or 2 bits as defined in Subclause 5.1.4.2 of [6, TS 38.214]. - // is the number of ZP CSI-RS resource sets in the higher layer parameter zp-CSI-RS-Resource - uint8_t n_zp_bits = pdsch_config.n_zp_CSI_RS_ResourceId; - // 17 FREQ_HOPPING_FLAG - // freqHopping is defined by higher layer parameter frequencyHopping from IE PUSCH-Config. Values are ENUMERATED{mode1, mode2} - frequencyHopping_t f_hopping = pusch_config.frequencyHopping; - uint8_t freqHopping = 0; - - if ((f_hopping==f_hop_mode1)||(f_hopping==f_hop_mode2)) freqHopping = 1; - - // 28 DAI - pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook = pdsch_config.pdsch_HARQ_ACK_Codebook; - uint8_t n_dai = 0; - uint8_t n_serving_cell_dl = 1; // this is hardcoded to 1 as we need to get this value from RRC higher layers parameters. FIXME!!! - - if ((pdsch_HARQ_ACK_Codebook == dynamic) && (n_serving_cell_dl == 1)) n_dai = 2; - - if ((pdsch_HARQ_ACK_Codebook == dynamic) && (n_serving_cell_dl > 1)) n_dai = 4; - - // 29 FIRST_DAI - uint8_t codebook_HARQ_ACK = 0; // We need to get this value to calculate number of bits of fields 1st DAI and 2nd DAI. - - if (pdsch_HARQ_ACK_Codebook == semiStatic) codebook_HARQ_ACK = 1; - - if (pdsch_HARQ_ACK_Codebook == dynamic) codebook_HARQ_ACK = 2; - - // 30 SECOND_DAI - uint8_t n_HARQ_ACK_sub_codebooks = 0; // We need to get this value to calculate number of bits of fields 1st DAI and 2nd DAI. FIXME!!! - // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND - uint8_t pdsch_harq_t_ind = (uint8_t)ceil(log2(pucch_config_dedicated.dl_DataToUL_ACK[0])); - // 36 SRS_RESOURCE_IND - // n_SRS is the number of configured SRS resources in the SRS resource set associated with the higher layer parameter usage of value 'codeBook' or 'nonCodeBook' - // from SRS_ResourceSet_t type we should get the information of the usage parameter (with possible values beamManagement, codebook, nonCodebook, antennaSwitching) - // at frame_parms->srs_nr->p_SRS_ResourceSetList[]->usage - uint8_t n_SRS = ue->srs.number_srs_Resource_Set; - // 37 PRECOD_NBR_LAYERS - // 38 ANTENNA_PORTS - txConfig_t txConfig = pusch_config.txConfig; - transformPrecoder_t transformPrecoder = pusch_config.transformPrecoder; - codebookSubset_t codebookSubset = pusch_config.codebookSubset; - uint8_t maxRank = pusch_config.maxRank; - uint8_t num_antenna_ports = 1; // this is hardcoded. We need to get the real value FIXME!!! - uint8_t precond_nbr_layers_bits = 0; - uint8_t antenna_ports_bits_ul = 0; - - // searching number of bits at tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2 - if (txConfig == txConfig_codebook) { - if (num_antenna_ports == 4) { - if ((transformPrecoder == transformPrecoder_disabled) && ((maxRank == 2)||(maxRank == 3)||(maxRank == 4))) { // Table 7.3.1.1.2-2 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=6; - - if (codebookSubset == codebookSubset_partialAndNonCoherent) precond_nbr_layers_bits=5; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=4; - } - - if (((transformPrecoder == transformPrecoder_enabled)||(transformPrecoder == transformPrecoder_disabled)) && (maxRank == 1)) { // Table 7.3.1.1.2-3 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=5; - - if (codebookSubset == codebookSubset_partialAndNonCoherent) precond_nbr_layers_bits=4; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=2; - } - } - - if (num_antenna_ports == 2) { - if ((transformPrecoder == transformPrecoder_disabled) && (maxRank == 2)) { // Table 7.3.1.1.2-4 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=4; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=2; - } - - if (((transformPrecoder == transformPrecoder_enabled)||(transformPrecoder == transformPrecoder_disabled)) && (maxRank == 1)) { // Table 7.3.1.1.2-5 - if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=3; - - if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=1; - } - } - } - - if (txConfig == txConfig_nonCodebook) { - } - - // searching number of bits at tables 7.3.1.1.2-6/7/8/9/10/11/12/13/14/15/16/17/18/19 - if((dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)) { - if ((transformPrecoder == transformPrecoder_enabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 2; - - if ((transformPrecoder == transformPrecoder_enabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 4; - - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 3; - - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 4; - } - - if((dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type2)) { - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 4; - - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 5; - } - - // for format 1_1 number of bits as defined by Tables 7.3.1.2.2-1/2/3/4 - uint8_t antenna_ports_bits_dl = 0; - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len1)) antenna_ports_bits_dl = 4; // Table 7.3.1.2.2-1 - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len2)) antenna_ports_bits_dl = 5; // Table 7.3.1.2.2-2 - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type2) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len1)) antenna_ports_bits_dl = 5; // Table 7.3.1.2.2-3 - - if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type2) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len2)) antenna_ports_bits_dl = 6; // Table 7.3.1.2.2-4 - - // 39 TCI - uint8_t tci_bits=0; - - if (pdcch_vars2->coreset[p].tciPresentInDCI == tciPresentInDCI_enabled) tci_bits=3; - - // 42 CSI_REQUEST - // reportTriggerSize is defined in the CSI-MeasConfig IE (TS 38.331). - // Size of CSI request field in DCI (bits). Corresponds to L1 parameter 'ReportTriggerSize' (see 38.214, section 5.2) - uint8_t reportTriggerSize = csi_MeasConfig.reportTriggerSize; // value from 0..6 - // 43 CBGTI - // for format 0_1 - uint8_t maxCodeBlockGroupsPerTransportBlock = 0; - - if (PUSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock != 0) - maxCodeBlockGroupsPerTransportBlock = (uint8_t)PUSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock; - - // for format 1_1, as defined in Subclause 5.1.7 of [6, TS38.214] - uint8_t maxCodeBlockGroupsPerTransportBlock_dl = 0; - - if (PDSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock_dl != 0) - maxCodeBlockGroupsPerTransportBlock_dl = pdsch_config.maxNrofCodeWordsScheduledByDCI; // FIXME!!! - - // 44 CBGFI - uint8_t cbgfi_bit = PDSCH_ServingCellConfig.codeBlockGroupFlushIndicator; - // 45 PTRS_DMRS - // 0 bit if PTRS-UplinkConfig is not configured and transformPrecoder=disabled, or if transformPrecoder=enabled, or if maxRank=1 - // 2 bits otherwise - uint8_t ptrs_dmrs_bits=0; //FIXME!!! - // 46 BETA_OFFSET_IND - // at IE PUSCH-Config, beta_offset indicator – 0 if the higher layer parameter betaOffsets = semiStatic; otherwise 2 bits - // uci-OnPUSCH - // Selection between and configuration of dynamic and semi-static beta-offset. If the field is absent or released, the UE applies the value 'semiStatic' and the BetaOffsets - uint8_t betaOffsets = 0; - - if (pusch_config.uci_onPusch.betaOffset_type == betaOffset_semiStatic); - - if (pusch_config.uci_onPusch.betaOffset_type == betaOffset_dynamic) betaOffsets = 2; - - // 47 DMRS_SEQ_INI - uint8_t dmrs_seq_ini_bits_ul = 0; - uint8_t dmrs_seq_ini_bits_dl = 0; - - //1 bit if both scramblingID0 and scramblingID1 are configured in DMRS-UplinkConfig - if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.scramblingID0 != 0) && (dmrs_UplinkConfig.scramblingID1 != 0)) dmrs_seq_ini_bits_ul = 1; - - //1 bit if both scramblingID0 and scramblingID1 are configured in DMRS-DownlinkConfig - if ((dmrs_DownlinkConfig.scramblingID0 != 0) && (dmrs_DownlinkConfig.scramblingID0 != 0)) dmrs_seq_ini_bits_dl = 1; - - /* - * For format 2_2 - * - * This format supports power control commands for semi-persistent scheduling. - * As we can already support power control commands dynamically with formats 0_0/0_1 (TPC PUSCH) and 1_0/1_1 (TPC PUCCH) - * - * This format will be implemented in the future FIXME!!! - * - */ - // 5 BLOCK_NUMBER: The parameter tpc-PUSCH or tpc-PUCCH provided by higher layers determines the index to the block number for an UL of a cell - // The following fields are defined for each block: Closed loop indicator and TPC command - // 6 CLOSE_LOOP_IND - // 41 TPC_CMD - uint8_t tpc_cmd_bit_2_2 = 2; - /* - * For format 2_3 - * - * This format is used for power control of uplink sounding reference signals for devices which have not coupled SRS power control to the PUSCH power control - * either because independent control is desirable or because the device is configured without PUCCH and PUSCH - * - * This format will be implemented in the future FIXME!!! - * - */ - // 40 SRS_REQUEST - // 41 TPC_CMD - uint8_t tpc_cmd_bit_2_3 = 0; - uint8_t dci_field_size_table [NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = { // This table contains the number of bits for each field (row) contained in each dci format (column). - // The values of the variables indicate field sizes in number of bits - //Format0_0 Format0_1 Format1_0 Format1_1 Formats2_0/1/2/3 - { - 1, 1, (((crc_scrambled == _p_rnti) || (crc_scrambled == _si_rnti) || (crc_scrambled == _ra_rnti)) ? 0:1), - 1, 0,0,0,0 - }, // 0 IDENTIFIER_DCI_FORMATS: - { - 0, ((crossCarrierSchedulingConfig_ind == 0) ? 0:3), - 0, ((crossCarrierSchedulingConfig_ind == 0) ? 0:3), - 0,0,0,0 - }, // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] - {0, (sul_ind == 0)?0:1, 0, 0, 0,0,0,0}, // 2 SUL_IND_0_1: - {0, 0, 0, 0, 1,0,0,0}, // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] - {0, 0, 0, 0, 0,1,0,0}, // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits - {0, 0, 0, 0, 0,0,0,0}, // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3 - {0, 0, 0, 0, 0,0,1,0}, // 6 CLOSE_LOOP_IND - { - 0, (uint8_t)ceil(log2(n_UL_BWP_RRC)), - 0, (uint8_t)ceil(log2(n_DL_BWP_RRC)), - 0,0,0,0 - }, // 7 BANDWIDTH_PART_IND: - { - 0, 0, ((crc_scrambled == _p_rnti) ? 2:0), - 0, 0,0,0,0 - }, // 8 SHORT_MESSAGE_IND 2 bits if crc scrambled with P-RNTI - { - 0, 0, ((crc_scrambled == _p_rnti) ? 8:0), - 0, 0,0,0,0 - }, // 9 SHORT_MESSAGES 8 bit8 if crc scrambled with P-RNTI - { - (uint8_t)(ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)))-n_UL_hopping, - n_bits_freq_dom_res_assign_ul, - 0, 0, 0,0,0,0 - }, // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - // (NOTE 1) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is larger than the payload size of the DCI format 1_0 monitored in common search space - // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 - // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0 - { - 0, 0, (uint8_t)ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2)), - n_bits_freq_dom_res_assign_dl, - 0,0,0,0 - }, // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - { - 4, (uint8_t)log2(pusch_alloc_list), - 4, (uint8_t)log2(pdsch_alloc_list), - 0,0,0,0 - }, // 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - // where I the number of entries in the higher layer parameter pusch-AllocationList - { - 0, 0, 1, (((dl_res_alloc_type_0==1) &&(dl_res_alloc_type_1==0))?0:1), - 0,0,0,0 - }, // 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - {0, 0, 0, prb_BundlingType_size, 0,0,0,0}, // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - {0, 0, 0, rateMatching_bits, 0,0,0,0}, // 15 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set - {0, 0, 0, n_zp_bits, 0,0,0,0}, // 16 ZP_CSI_RS_TRIGGER: - { - 1, (((ul_res_alloc_type_0==1) &&(ul_res_alloc_type_1==0))||(freqHopping == 0))?0:1, - 0, 0, 0,0,0,0 - }, // 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - {0, 0, 0, 5, 0,0,0,0}, // 18 TB1_MCS: - {0, 0, 0, 1, 0,0,0,0}, // 19 TB1_NDI: - {0, 0, 0, 2, 0,0,0,0}, // 20 TB1_RV: - {0, 0, 0, 5, 0,0,0,0}, // 21 TB2_MCS: - {0, 0, 0, 1, 0,0,0,0}, // 22 TB2_NDI: - {0, 0, 0, 2, 0,0,0,0}, // 23 TB2_RV: - {5, 5, 5, 0, 0,0,0,0}, // 24 MCS: - {1, 1, (crc_scrambled == _c_rnti)?1:0,0, 0,0,0,0}, // 25 NDI: - { - 2, 2, (((crc_scrambled == _c_rnti) || (crc_scrambled == _si_rnti)) ? 2:0), - 0, 0,0,0,0 - }, // 26 RV: - {4, 4, (crc_scrambled == _c_rnti)?4:0,4, 0,0,0,0}, // 27 HARQ_PROCESS_NUMBER: - {0, 0, (crc_scrambled == _c_rnti)?2:0,n_dai, 0,0,0,0}, // 28 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI - // 0 otherwise - {0, codebook_HARQ_ACK, 0, 0, 0,0,0,0}, // 29 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK // 2 bits for dynamic HARQ-ACK codebook with single HARQ-ACK codebook - { - 0, (((codebook_HARQ_ACK == 2) &&(n_HARQ_ACK_sub_codebooks==2))?2:0), - 0, 0, 0,0,0,0 - }, // 30 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks // 0 bits otherwise - { - 0, 0, (((crc_scrambled == _p_rnti) || (crc_scrambled == _ra_rnti)) ? 2:0), - 0, 0,0,0,0 - }, // 31 TB_SCALING - {2, 2, 0, 0, 0,0,0,0}, // 32 TPC_PUSCH: - {0, 0, (crc_scrambled == _c_rnti)?2:0,2, 0,0,0,0}, // 33 TPC_PUCCH: - {0, 0, (crc_scrambled == _c_rnti)?3:0,3, 0,0,0,0}, // 34 PUCCH_RESOURCE_IND: - {0, 0, (crc_scrambled == _c_rnti)?3:0,pdsch_harq_t_ind, 0,0,0,0}, // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - {0, (uint8_t)log2(n_SRS), 0, 0, 0,0,0,0}, // 36 SRS_RESOURCE_IND: - {0, precond_nbr_layers_bits, 0, 0, 0,0,0,0}, // 37 PRECOD_NBR_LAYERS: - {0, antenna_ports_bits_ul, 0, antenna_ports_bits_dl, 0,0,0,0}, // 38 ANTENNA_PORTS: - {0, 0, 0, tci_bits, 0,0,0,0}, // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits - {0, (sul_ind == 0)?2:3, 0, (sul_ind == 0)?2:3, 0,0,0,2}, // 40 SRS_REQUEST: - { - 0, 0, 0, 0, 0,0,tpc_cmd_bit_2_2, - tpc_cmd_bit_2_3 - }, - // 41 TPC_CMD: - {0, reportTriggerSize, 0, 0, 0,0,0,0}, // 42 CSI_REQUEST: - { - 0, maxCodeBlockGroupsPerTransportBlock, - 0, maxCodeBlockGroupsPerTransportBlock_dl, - 0,0,0,0 - }, // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH - {0, 0, 0, cbgfi_bit, 0,0,0,0}, // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator - {0, ptrs_dmrs_bits, 0, 0, 0,0,0,0}, // 45 PTRS_DMRS: - {0, betaOffsets, 0, 0, 0,0,0,0}, // 46 BETA_OFFSET_IND: - {0, dmrs_seq_ini_bits_ul, 0, dmrs_seq_ini_bits_dl, 0,0,0,0}, // 47 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding - // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise - {0, 1, 0, 0, 0,0,0,0}, // 48 UL_SCH_IND: value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH - {0, 0, 0, 0, 0,0,0,0}, // 49 PADDING_NR_DCI: - // (NOTE 2) If DCI format 0_0 is monitored in common search space - // and if the number of information bits in the DCI format 0_0 prior to padding - // is less than the payload size of the DCI format 1_0 monitored in common search space - // zeros shall be appended to the DCI format 0_0 - // until the payload size equals that of the DCI format 1_0 - {(sul_ind == 0)?0:1, 0, 0, 0, 0,0,0,0}, // 50 SUL_IND_0_0: - {0, 0, 0, 0, 0,0,0,0}, // 51 RA_PREAMBLE_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - {0, 0, 0, 0, 0,0,0,0}, // 52 SUL_IND_1_0 (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - {0, 0, 0, 0, 0,0,0,0}, // 53 SS_PBCH_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - {0, 0, 0, 0, 0,0,0,0}, // 54 PRACH_MASK_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) - { - 0, 0, ((crc_scrambled == _p_rnti)?6:(((crc_scrambled == _si_rnti) || (crc_scrambled == _ra_rnti))?16:0)), - 0, 0,0,0,0 - } // 55 RESERVED_NR_DCI - }; - // NOTE 1: adjustments in freq_dom_resource_assignment_UL to be done if necessary - // NOTE 2: adjustments in padding to be done if necessary - uint8_t dci_size [8] = {0,0,0,0,0,0,0,0}; // will contain size for each format - - for (int i=0 ; i i=%d, j=%d\n", i, j); - //#endif - for (int j=0; j position in table is 2) - dci_fields_sizes[j][i] = dci_field_size_table[j][i]; // dci_fields_sizes[j] contains the sizes of each field (j) for a determined format i - //} - } - -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_size[%d]=%d for n_RB_ULBWP=%d\n", - i,dci_size[i],n_RB_ULBWP); -#endif - } - -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_fields_sizes[][] = { \n"); - - for (int j=0; j dci_size[2])) { - dci_field_size_table[SUL_IND_0_0][0] = 0; - dci_size[0]=dci_size[0]-1; - } - // if ((format == format0_0) || (format == format1_0)) { - // According to Section 7.3.1.1.1 in TS 38.212 - // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding - // is less than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell, - // zeros shall be appended to the DCI format 0_0 until the payload size equals that of the DCI format 1_0. - if (dci_size[0] < dci_size[2]) { // '0' corresponding to index for format0_0 and '2' corresponding to index of format1_0 - //if (format == format0_0) { - dci_fields_sizes[PADDING_NR_DCI][0] = dci_size[2] - dci_size[0]; - dci_size[0] = dci_size[2]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); -#endif - //} - } - // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding - // is larger than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell, - // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 is reduced - // such that the size of DCI format 0_0 equals to the size of the DCI format 1_0.. - if (dci_size[0] > dci_size[2]) { - //if (format == format0_0) { - dci_fields_sizes[FREQ_DOM_RESOURCE_ASSIGNMENT_UL][0] -= (dci_size[0] - dci_size[2]); - dci_size[0] = dci_size[2]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); -#endif - //} - } - /* - * TS 38.212 subclause 7.3.1.1.2 - * For a UE configured with SUL in a cell: - * if PUSCH is configured to be transmitted on both the SUL and the non-SUL of the cell and - * if the number of information bits in format 0_1 for the SUL - * is not equal to the number of information bits in format 0_1 for the non-SUL, - * zeros shall be appended to smaller format 0_1 until the payload size equals that of the larger format 0_1 - * - * Not implemented. FIXME!!! - * - */ - // } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_fields_sizes[][] = { \n"); - for (int j=0; jframe_parms, nr_tti_rx); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> searSpaceType=%d\n",do_common); + LOG_DD("searSpaceType=%d\n",do_common); + LOG_DD("%s_dci_format=%d\n",do_common?"uss":"css",css_dci_format); - if (do_common==0) { - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> css_dci_format=%d\n",css_dci_format); - } else { - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> uss_dci_format=%d\n",uss_dci_format); - } - -#endif // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces if (do_common==0) { // COMMON SearchSpaceType assigned to current SearchSpace/CORESET @@ -2737,18 +1676,14 @@ uint8_t nr_dci_decoding_procedure(int s, // for format0_0 and format1_0, first we calculate dci pdu size format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2776,16 +1711,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_0, first we calculate dci pdu size format_2_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_sfi_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,4); format_2_0_size_bytes = (format_2_0_size_bits%8 == 0) ? (uint8_t)floor(format_2_0_size_bits/8) : (uint8_t)(floor(format_2_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n", css_dci_format,format_2_0_size_bits,format_2_0_size_bytes); -#endif for (int aggregationLevelSFI = 0; aggregationLevelSFI<5 ; aggregationLevelSFI++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, @@ -2810,16 +1741,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_1, first we calculate dci pdu size format_2_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_int_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,5); format_2_1_size_bytes = (format_2_1_size_bits%8 == 0) ? (uint8_t)floor(format_2_1_size_bits/8) : (uint8_t)(floor(format_2_1_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_1_size_bits=%d, format2_1_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_1_size_bits=%d, format2_1_size_bytes=%d\n", css_dci_format,format_2_1_size_bits,format_2_1_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, @@ -2844,16 +1771,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_2, first we calculate dci pdu size format_2_2_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_tpc_pucch_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,6); format_2_2_size_bytes = (format_2_2_size_bits%8 == 0) ? (uint8_t)floor(format_2_2_size_bits/8) : (uint8_t)(floor(format_2_2_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_2_size_bits=%d, format2_2_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_2_size_bits=%d, format2_2_size_bytes=%d\n", css_dci_format,format_2_2_size_bits,format_2_2_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, @@ -2878,16 +1801,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_1, first we calculate dci pdu size format_2_3_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_tpc_srs_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,7); format_2_3_size_bytes = (format_2_3_size_bits%8 == 0) ? (uint8_t)floor(format_2_3_size_bits/8) : (uint8_t)(floor(format_2_3_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_3_size_bits=%d, format2_3_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_3_size_bits=%d, format2_3_size_bytes=%d\n", css_dci_format,format_2_3_size_bits,format_2_3_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, @@ -2913,18 +1832,14 @@ uint8_t nr_dci_decoding_procedure(int s, // for format0_0 and format1_0, first we calculate dci pdu size format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2948,18 +1863,14 @@ uint8_t nr_dci_decoding_procedure(int s, // for format0_0 and format1_0, first we calculate dci pdu size format_0_1_1_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,1); format_0_1_1_1_size_bytes = (format_0_1_1_1_size_bits%8 == 0) ? (uint8_t)floor(format_0_1_1_1_size_bits/8) : (uint8_t)(floor(format_0_1_1_1_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_1_1_1_size_bits=%d, format_0_1_1_1_size_bytes=%d\n", + LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_1_1_1_size_bits=%d, format_0_1_1_1_size_bytes=%d\n", css_dci_format,format_0_1_1_1_size_bits,format_0_1_1_1_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2982,16 +1893,9 @@ uint8_t nr_dci_decoding_procedure(int s, *crc_scrambled = crc_scrambled_; *format_found = format_found_; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> at the end crc_scrambled=%d and format_found=%d\n",*crc_scrambled,*format_found); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> at the end dci_cnt=%d \n",dci_cnt); -#endif + LOG_DD("at the end crc_scrambled=%d and format_found=%d\n",*crc_scrambled,*format_found); + LOG_DD("at the end dci_cnt=%d \n",dci_cnt); return(dci_cnt); } #endif - - - diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c index 947483e8f0..17ecce714a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c @@ -37,7 +37,7 @@ //#include "PHY/extern.h" //#include "SCHED/defs.h" #ifdef DEBUG_DCI_TOOLS -#include "PHY/vars.h" + #include "PHY/vars.h" #endif #include "assertions.h" @@ -54,1025 +54,12 @@ #define NR_PDCCH_DCI_TOOLS //#define NR_PDCCH_DCI_TOOLS_DEBUG -typedef unsigned __int128 uint128_t; -int8_t nr_delta_PUSCH_abs[4] = {-4,-1,1,4}; -int8_t nr_delta_PUSCH_acc[4] = {-1,0,1,3}; -int8_t *nr_delta_PUCCH_lut = nr_delta_PUSCH_acc; -#ifdef NR_PDCCH_DCI_TOOLS -uint16_t nr_dci_field(uint64_t dci_pdu[2], - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS], - uint8_t dci_field) -{ - int dci_size=0; - - for (int i=0;i 64 bits, not supported for now\n", - dci_size); - - uint16_t first_bit_position = dci_size; - - for (int i=0; i<=dci_field ; i++){ - first_bit_position = first_bit_position - dci_fields_sizes[i]; - } - - /*uint16_t tmp1 = ((*dci_pdu>>first_bit_position)&((1<>i)&1)<<(dci_fields_sizes[dci_field]-i-1);*/ - - return ((uint16_t)(*dci_pdu>>first_bit_position)&((1< (1 1010 1000 1001 0000 0000 0111 1000 1001 1010 0) - * then we will do a right-shit of dci_length-13 positions -> (1 1010 1000 1001). And this is the content of the freq_dom_resource_assignment_DL field - * - * - * At the moment we have implemented the following formats: - * - * Format 0_0, that contains the following fields according to Specification 38.212 V15.1.1 Section 7.3.1 - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 32 TPC_PUSCH: - * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - * 50 SUL_IND_0_0: - * - * Format 0_1, that contains the following fields - * with CRC scrambled by C-RNTI or CS-RNTI or SP-CSI-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 1 CARRIER_IND - * 2 SUL_IND_0_1 - * 7 BANDWIDTH_PART_IND - * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 29 FIRST_DAI - * 30 SECOND_DAI - * 32 TPC_PUSCH: - * 36 SRS_RESOURCE_IND: - * 37 PRECOD_NBR_LAYERS: - * 38 ANTENNA_PORTS: - * 40 SRS_REQUEST: - * 42 CSI_REQUEST: - * 43 CBGTI - * 45 PTRS_DMRS - * 46 BETA_OFFSET_IND - * 47 DMRS_SEQ_INI - * 48 UL_SCH_IND - * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - * - * Format 1_0, that contains the following fields - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * 34 PUCCH_RESOURCE_IND: - * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - * 55 RESERVED_NR_DCI - * - * If the CRC of the DCI format 1_0 is scrambled by C-RNTI and the "Frequency domain resource assignment" field are of all ones, - * the DCI format 1_0 is for random access procedure initiated by a PDCCH order. - * This is not implemented, but the fields are already included: FIXME!!! - * - * with CRC scrambled by P-RNTI - * 8 SHORT_MESSAGE_IND - * 9 SHORT_MESSAGES - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 31 TB_SCALING - * 55 RESERVED_NR_DCI - * - * with CRC scrambled by SI-RNTI - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 26 RV: - * 55 RESERVED_NR_DCI - * - * with CRC scrambled by RA-RNTI - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 31 TB_SCALING - * 55 RESERVED_NR_DCI - * - * with CRC scrambled by TC-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * - * Format 1_1, that contains the following fields - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 1 CARRIER_IND: - * 7 BANDWIDTH_PART_IND: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 14 PRB_BUNDLING_SIZE_IND: - * 15 RATE_MATCHING_IND: - * 16 ZP_CSI_RS_TRIGGER: - * 18 TB1_MCS: - * 19 TB1_NDI: - * 20 TB1_RV: - * 21 TB2_MCS: - * 22 TB2_NDI: - * 23 TB2_RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * 34 PUCCH_RESOURCE_IND: - * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - * 38 ANTENNA_PORTS: - * 39 TCI: - * 40 SRS_REQUEST: - * 43 CBGTI: - * 44 CBGFI: - * 47 DMRS_SEQ_INI: - * - * We have not implemented the following formats: - * - * Format 2_0 - * Used for notifying the slot format - * - * Format 2_1 - * Used for notifying the PRB(s) and OFDM symbol(s) where UE may assume no transmission is intended for the UE - * - * Format 2_2 - * This format supports power control commands for semi-persistent scheduling. - * As we can already support power control commands dynamically with formats 0_0/0_1 (TPC PUSCH) and 1_0/1_1 (TPC PUCCH) - * This format will be implemented in the future FIXME!!! - * - * Format 2_3 - * This format is used for power control of uplink sounding reference signals for devices which have not coupled SRS power control to the PUSCH power control - * either because independent control is desirable or because the device is configured without PUCCH and PUSCH - * This format will be implemented in the future FIXME!!! - * - */ - uint8_t dci_fields_sizes_format[NBR_NR_DCI_FIELDS] = {0}; - for (int m=0; m> (DCI_MAX_SIZE - dci_length); // this variable will help to remove the bits of other fields when left-switching - uint8_t dci_field=0; -// uint8_t sizes_count=0; -// uint8_t left_shift=0; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Entering function nr_extract_dci_info() with dci_pdu=%lx %lx dci_length=%d\n", - dci_pdu[0],dci_pdu[1], dci_length); - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> for format %d, dci_fields_sizes {",dci_format); - for (int i=0; iDCINdi; - - - /* - * Some dci fields need to be interpreted before the others. - */ - if (dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format] != 0) { // E.g: 27 HARQ_PROCESS_NUMBER (27 is the position in dci_fields_sizes array for field HARQ_PROCESS_NUMBER) - //for (int i=0; i<=HARQ_PROCESS_NUMBER; i++) left_shift = left_shift + dci_fields_sizes[i][dci_format]; - nr_pdci_info_extracted->harq_process_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,HARQ_PROCESS_NUMBER); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format])); - //left_shift = 0; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); - #endif - } -/* - if ((dci_format == format1_0) || (dci_format == format1_1)) { - if (rnti==crc_scrambled_values[_SI_RNTI_]) { - ue->dlsch_SI[eNB_id]->active = 1; - } else if (rnti==crc_scrambled_values[_P_RNTI_]) { - ue->dlsch_p[eNB_id]->active = 1; - } else if (rnti==crc_scrambled_values[_RA_RNTI_]) { - ue->dlsch_ra[eNB_id]->active = 1; - } else { - pdlsch0->active = 1; - } - pdlsch0->rnti = rnti; - pdlsch0_harq->codeword = 0; - pdlsch0_harq->Nl = 1; -// pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; - pdlsch0_harq->dl_power_off = 1; //no power offset - - if ((rnti==crc_scrambled_values[_SI_RNTI_]) || (rnti==crc_scrambled_values[_P_RNTI_]) || (rnti==crc_scrambled_values[_RA_RNTI_])) { - pdlsch0_harq->round = 0; - pdlsch0_harq->status = ACTIVE; - } else { - } - } -*/ - for (dci_field=0; dci_field dci_fields_sizes[%d][%d] = %d\n",dci_field,dci_format,dci_fields_sizes[dci_field][dci_format]); - #endif - - switch (dci_field){ - case IDENTIFIER_DCI_FORMATS: // 0 IDENTIFIER_DCI_FORMATS: (field defined for format0_0,format0_1,format1_0,format1_1,format2_0,format2_1,format2_2,format2_3) - // if format 0_0: The value of this bit field is always set to 0, indicating an UL DCI format (TS38.212 Section 7.3.1.1.1) - // if format 1_0: The value of this bit field is always set to 1, indicating a DL DCI format (TS38.212 Section 7.3.1.2.1) - nr_pdci_info_extracted->identifier_dci_formats = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->identifier_dci_formats=%x\n",nr_pdci_info_extracted->identifier_dci_formats); - #endif - break; - - case CARRIER_IND: // 1 CARRIER_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) - // 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] - nr_pdci_info_extracted->carrier_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); -#ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->carrier_ind=%x\n",nr_pdci_info_extracted->carrier_ind); -#endif - break; - case SUL_IND_0_1: // 2 SUL_IND_0_1: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->sul_ind_0_1 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_1=%x\n",nr_pdci_info_extracted->sul_ind_0_1); - #endif - break; - - case SLOT_FORMAT_IND: // 3 SLOT_FORMAT_IND: (field defined for -,-,-,-,format2_0,-,-,-) - // size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] - nr_pdci_info_extracted->slot_format_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->slot_format_ind=%x\n",nr_pdci_info_extracted->slot_format_ind); - #endif - break; - case PRE_EMPTION_IND: // 4 PRE_EMPTION_IND: (field defined for -,-,-,-,-,format2_1,-,-) - // size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits - nr_pdci_info_extracted->pre_emption_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pre_emption_ind=%x\n",nr_pdci_info_extracted->pre_emption_ind); - #endif - break; - case BLOCK_NUMBER: // 5 BLOCK_NUMBER: (field defined for -,-,-,-,-,-,-,format2_3) - // starting position of a block is determined by the parameter startingBitOfFormat2_3 - nr_pdci_info_extracted->block_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->block_number=%x\n",nr_pdci_info_extracted->block_number); - #endif - break; - case CLOSE_LOOP_IND: // 6 CLOSE_LOOP_IND: (field defined for -,-,-,-,-,-,format2_2,-) - // The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits - nr_pdci_info_extracted->close_loop_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->close_loop_ind=%x\n",nr_pdci_info_extracted->close_loop_ind); - #endif - break; - case BANDWIDTH_PART_IND: // 7 BANDWIDTH_PART_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->bandwidth_part_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->bandwidth_part_ind=%x\n",nr_pdci_info_extracted->bandwidth_part_ind); - #endif - break; - - case SHORT_MESSAGE_IND: // 8 SHORT_MESSAGE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) - nr_pdci_info_extracted->short_message_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->short_message_ind=%x\n",nr_pdci_info_extracted->short_message_ind); - #endif - break; - - case SHORT_MESSAGES: // 9 SHORT_MESSAGES: (field defined for -,-,format1_0,format1_1,-,-,-,-) - nr_pdci_info_extracted->short_messages = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->short_messages=%x\n",nr_pdci_info_extracted->short_messages); - #endif - break; - - case FREQ_DOM_RESOURCE_ASSIGNMENT_UL: // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: (field defined for format0_0,format0_1,-,-,-,-,-,-) - // PUSCH hopping with resource allocation type 1 not considered - // According to 38.214 V15.1.0 Section 6.1.2.2 Two uplink resource allocation schemes, type 0 and type 1, are supported. - // The UE shall assume that when the scheduling PDCCH is received with DCI format 0_0, then uplink resource allocation type 1 is used. - nr_pdci_info_extracted->freq_dom_resource_assignment_UL = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - /*if (dci_format == format0_1){ // uplink resource allocation type 0 or 1 can be used - } - if (dci_format == format0_0){ // only uplink resource allocation type 1 - // At the moment we are supporting only format 1_0 (and not format 1_1), so we only support resource allocation type 1 (and not type 0). - // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): - // RIV = n_RB_ULBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_ULBWP/2) - // RIV = n_RB_ULBWP * (n_RB_ULBWP - l_RB + 1) + (n_RB_ULBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_ULBWP/2) - // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_ULBWP/2) - l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_ULBWP) + 1; - start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_ULBWP; - // if (l_RB - 1) > floor (n_RB_ULBWP/2) we need to recalculate them using the following lines - tmp_RIV = n_RB_ULBWP * (l_RB - 1) + start_RB; - if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_ULBWP/2) and we need to recalculate l_RB and start_RB - l_RB = n_RB_ULBWP - l_RB + 2; - start_RB = n_RB_ULBWP - start_RB - 1; - } - ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_rb = start_RB; - ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->nb_rb = l_RB; - }*/ - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_UL=%x\n",nr_pdci_info_extracted->freq_dom_resource_assignment_UL); - //printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_ULBWP); - #endif - break; - - case FREQ_DOM_RESOURCE_ASSIGNMENT_DL: // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // According to 38.214 V15.1.0 Section 5.1.2.2 Two downlink resource allocation schemes, type 0 and type 1, are supported. - // The UE shall assume that when the scheduling grant is received with DCI format 1_0, then downlink resource allocation type 1 is used. - nr_pdci_info_extracted->freq_dom_resource_assignment_DL = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - /*if (dci_format == format1_1){ // uplink resource allocation type 0 or 1 can be used - } - if (dci_format == format1_0){ // only uplink resource allocation type 1 - // At the moment we are supporting only format 0_0 (and not format 0_1), so we only support resource allocation type 1 (and not type 0). - // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): - // RIV = n_RB_DLBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_DLBWP/2) - // RIV = n_RB_DLBWP * (n_RB_DLBWP - l_RB + 1) + (n_RB_DLBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_DLBWP/2) - // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_DLBWP/2) - l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_DLBWP) + 1; - start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_DLBWP; - // if (l_RB - 1) > floor (n_RB_DLBWP/2) we need to recalculate them using the following lines - tmp_RIV = n_RB_DLBWP * (l_RB - 1) + start_RB; - if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_DLBWP/2) and we need to recalculate l_RB and start_RB - l_RB = n_RB_DLBWP - l_RB + 2; - start_RB = n_RB_DLBWP - start_RB - 1; - } - pdlsch0_harq->nb_rb = l_RB; - pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number; - pdlsch0->active = 1; - pdlsch0->rnti = rnti; - }*/ - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_DL=%x, RIV = %d\n",nr_pdci_info_extracted->freq_dom_resource_assignment_DL,nr_pdci_info_extracted->freq_dom_resource_assignment_DL); - //printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_DLBWP); - /* - * According to TC 38.212 Subclause 7.3.1.2.1 (V15.2.0) (not implemented FIXME!!!) - * If the CRC of the DCI format 1_0 is scrambled by C-RNTI - * and the "Frequency domain resource assignment" field are of all ones, - * the DCI format 1_0 is for random access procedure initiated by a PDCCH order, - * with all remaining fields set as follows: - * - Random Access Preamble index (6 bits) - * - UL/SUL indicator (1 bit) - * - SS/PBCH index (6 bits) - * - PRACH Mask index (4 bits) - * - Reserved bits (10 bits) - * - */ - /* - * The following commented code is used to verify that l_RB and start_RB are correctly calculated - * - * - printf("\ns_RB\t"); - n_RB_DLBWP = 20; - for (int k = 0 ; k < n_RB_DLBWP; k++) printf("%d\t",k); - printf("\nl_RB"); - for (int j = 1 ; j <= n_RB_DLBWP; j++){ // l_RB - printf("\n%d\t",j); - for (int i = 0 ; i < n_RB_DLBWP; i++) { // start_RB - if ((j-1) <= (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { - tmp_RIV = n_RB_DLBWP * (j - 1) + i; - l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; - start_RB = tmp_RIV%n_RB_DLBWP; - printf("%d(%d,%d) ",tmp_RIV,l_RB,start_RB); - } - if ((j-1) > (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { - tmp_RIV = n_RB_DLBWP * (n_RB_DLBWP - j + 1) + (n_RB_DLBWP - 1 - i); - //l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; - //start_RB = tmp_RIV%n_RB_DLBWP; - l_RB = n_RB_DLBWP - (floor(tmp_RIV/n_RB_DLBWP) + 1) + 2; - start_RB = n_RB_DLBWP - (tmp_RIV%n_RB_DLBWP) - 1; - printf("%d*(%d,%d) ",tmp_RIV,l_RB,start_RB); - } - } - }*/ - #endif - break; - - case TIME_DOM_RESOURCE_ASSIGNMENT: // 12 TIME_DOM_RESOURCE_ASSIGNMENT: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) - // 0, 1, 2, 3, or 4 bits as defined in: - // Subclause 6.1.2.1 of [6, TS 38.214] for formats format0_0,format0_1 - // Subclause 5.1.2.1 of [6, TS 38.214] for formats format1_0,format1_1 - // The bitwidth for this field is determined as log2(I) bits, - // where I the number of entries in the higher layer parameter pusch-AllocationList - nr_pdci_info_extracted->time_dom_resource_assignment = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - /*if (dci_format == format0_0 || dci_format == format0_1){ // Subclause 6.1.2.1 of [6, TS 38.214] - k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - - } - if (dci_format == format1_0 || dci_format == format1_1){ // Subclause 5.1.2.1 of [6, TS 38.214] - // the Time domain resource assignment field of the DCI provides a row index of a higher layer configured table pdsch-symbolAllocation - // FIXME! To clarify which parameters to update after reception of row index - k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - }*/ - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->time_dom_resource_assignment=%x\n",nr_pdci_info_extracted->time_dom_resource_assignment); - #endif - break; - - case VRB_TO_PRB_MAPPING: // 13 VRB_TO_PRB_MAPPING: (field defined for -,format0_1,format1_0,format1_1,-,-,-,-) - //0 bit if resource allocation type 0 - //1 bit if resource allocation type 1 - //Table 7.3.1.1.2-33: VRB-to-PRB mapping - // 0 Non-interleaved - // 1 Interleaved - nr_pdci_info_extracted->vrb_to_prb_mapping = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->vrb_to_prb_mapping == 0) { // Non-interleaved - //} else { // Interleaved - // format 0_1 defined in TS 38.211 Section 6.3.1.7 - // formats 1_0 and 1_1 not defined yet - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->vrb_to_prb_mapping=%x\n",nr_pdci_info_extracted->vrb_to_prb_mapping); - #endif - break; - - case PRB_BUNDLING_SIZE_IND: // 14 PRB_BUNDLING_SIZE_IND: (field defined for -,-,-,format1_1,-,-,-,-) - // 0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - nr_pdci_info_extracted->prb_bundling_size_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->prb_bundling_size_ind=%x\n",nr_pdci_info_extracted->prb_bundling_size_ind); - #endif - break; - case RATE_MATCHING_IND: // 15 RATE_MATCHING_IND: (field defined for -,-,-,format1_1,-,-,-,-) - // 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set - nr_pdci_info_extracted->rate_matching_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rate_matching_ind=%x\n",nr_pdci_info_extracted->rate_matching_ind); - #endif - break; - case ZP_CSI_RS_TRIGGER: // 16 ZP_CSI_RS_TRIGGER: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->zp_csi_rs_trigger = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->zp_csi_rs_trigger=%x\n",nr_pdci_info_extracted->zp_csi_rs_trigger); - #endif - break; - - case FREQ_HOPPING_FLAG: // 17 FREQ_HOPPING_FLAG: (field defined for format0_0,format0_1,-,-,-,-,-,-) - // 0 bit if only resource allocation type 0 - // 1 bit otherwise, only applicable to resource allocation type 1, as defined in Subclause 6.3 of [6, TS 38.214] - nr_pdci_info_extracted->freq_hopping_flag = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->freq_hopping_flag != 0) { // PUSCH frequency hopping is performed (only resource allocation type 1) - - //} else { // PUSCH frequency hopping is not performed (only resource allocation type 1) - // At the moment PUSCH hopping is not implemented. We are considering that the bit is present and the value is '0' - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_hopping_flag=%x\n",nr_pdci_info_extracted->freq_hopping_flag); - #endif - break; - - case TB1_MCS: // 18 TB1_MCS: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb1_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb1_mcs; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_mcs=%x\n",nr_pdci_info_extracted->tb1_mcs); - #endif - break; - case TB1_NDI: // 19 TB1_NDI: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb1_ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb1_ndi; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_ndi=%x\n",nr_pdci_info_extracted->tb1_ndi); - #endif - break; - case TB1_RV: // 20 TB1_RV: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb1_rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb1_rv; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_rv=%x\n",nr_pdci_info_extracted->tb1_rv); - #endif - break; - case TB2_MCS: // 21 TB2_MCS: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb2_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb2_mcs; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_mcs=%x\n",nr_pdci_info_extracted->tb2_mcs); - #endif - break; - case TB2_NDI: // 22 TB2_NDI: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb2_ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb2_ndi; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_ndi=%x\n",nr_pdci_info_extracted->tb2_ndi); - #endif - break; - case TB2_RV: // 23 TB2_RV: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb2_rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb2_rv; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_rv=%x\n",nr_pdci_info_extracted->tb2_rv); - #endif - break; - - case MCS: // 24 MCS: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->mcs < 29) { - // if (dci_format == format0_0 || dci_format == format0_1) - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->mcs = nr_pdci_info_extracted->mcs; - // else - // pdlsch0_harq->mcs = nr_pdci_info_extracted->mcs; - //} else { - // return(0); - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->mcs=%x\n",nr_pdci_info_extracted->mcs); - #endif - break; - - case NDI: // 25 NDI: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (dci_format == format0_0 || dci_format == format0_1) { - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi = nr_pdci_info_extracted->ndi; - // if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx==1) { - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx=0; - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi; - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0; - // } else { - // if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi != nr_pdci_info_extracted->ndi) { // new SDU opportunity - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi; - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0; - // } - // } - //} else { - // if (rnti == crc_scrambled_values[_TC_RNTI_]) { //fix for standalone Contention Resolution Id - // pdlsch0_harq->DCINdi = (uint8_t)-1; - // } else { - // if ((prev_ndi != nr_pdci_info_extracted->ndi) || (pdlsch0_harq->first_tx==1)) { - // pdlsch0_harq->round = 0; - // pdlsch0_harq->first_tx = 0; - // pdlsch0_harq->status = ACTIVE; - // } - // pdlsch0_harq->DCINdi = nr_pdci_info_extracted->ndi; - // } - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ndi=%x\n",nr_pdci_info_extracted->ndi); - #endif - break; - - case RV: // 26 RV: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (dci_format == format0_0 || dci_format == format0_1) - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->rvidx = nr_pdci_info_extracted->rv; - //else - // pdlsch0_harq->rvidx = nr_pdci_info_extracted->rv; - //if ((prev_ndi == nr_pdci_info_extracted->ndi) && (pdlsch0_harq->rvidx != 0)) { // NDI has not been toggled but rv was increased by eNB: retransmission - // if (pdlsch0_harq->status == SCH_IDLE) { - // packet was actually decoded in previous transmission (ACK was missed by eNB) - // however, the round is not a good check as it might have been decoded in a retransmission prior to this one. - // skip pdsch decoding and report ack - - // pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.ack = 1; - // pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.send_harq_status; -#if 0 - // pdlsch0->active = 0; - // pdlsch0->harq_ack[nr_tti_rx].ack = 1; - // pdlsch0->harq_ack[nr_tti_rx].harq_id = nr_pdci_info_extracted->harq_process_number; - // pdlsch0->harq_ack[nr_tti_rx].send_harq_status = 1; -#endif - // } else { // normal retransmission, nothing special to do - // } - //} else { - // pdlsch0_harq->status = ACTIVE; - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rv=%x\n",nr_pdci_info_extracted->rv); - #endif - break; - - case HARQ_PROCESS_NUMBER: // 27 HARQ_PROCESS_NUMBER: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) - nr_pdci_info_extracted->harq_process_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); - #endif - break; - - case DAI_: // 28 DAI_: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // For format1_0: 2 bits as defined in Subclause 9.1.3 at TS 38.213 - // For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI - // 0 otherwise - nr_pdci_info_extracted->dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.vDAI_DL = nr_pdci_info_extracted->dai+1; - //pdlsch0->harq_ack[nr_tti_rx].vDAI_DL = nr_pdci_info_extracted->dai+1; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dai=%x\n",nr_pdci_info_extracted->dai); - #endif - break; - - case FIRST_DAI: // 29 FIRST_DAI: (field defined for -,format0_1,-,-,-,-,-,-) - // (1 or 2 bits) 1 bit for semi-static HARQ-ACK - nr_pdci_info_extracted->first_dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->first_dai=%x\n",nr_pdci_info_extracted->first_dai); - #endif - break; - case SECOND_DAI: // 30 SECOND_DAI: (field defined for -,format0_1,-,-,-,-,-,-) - // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks - nr_pdci_info_extracted->second_dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->second_dai=%x\n",nr_pdci_info_extracted->second_dai); - #endif - break; - - case TB_SCALING: // 31 TB_SCALING: (field defined for -,format0_1,-,-,-,-,-,-) - // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks - nr_pdci_info_extracted->tb_scaling = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb_scaling=%x\n",nr_pdci_info_extracted->tb_scaling); - #endif - break; - - case TPC_PUSCH: // 32 TPC_PUSCH: (field defined for format0_0,format0_1,-,-,-,-,-,-) - // defined in Subclause 7.1.1 TS 38.213 - nr_pdci_info_extracted->tpc_pusch = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC = nr_pdci_info_extracted->tpc_pusch; - //if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { - // ulsch0->f_pusch += nr_delta_PUSCH_acc[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; - //} else { - // ulsch0->f_pusch = nr_delta_PUSCH_abs[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pusch=%x\n",nr_pdci_info_extracted->tpc_pusch); - #endif - break; - - case TPC_PUCCH: // 33 TPC_PUCCH: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // defined in Subclause 7.2.1 TS 38.213 - nr_pdci_info_extracted->tpc_pucch = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->delta_PUCCH = nr_delta_PUCCH_lut[nr_pdci_info_extracted->tpc_pucch &3]; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pucch=%x\n",nr_pdci_info_extracted->tpc_pucch); - #endif - break; - - case PUCCH_RESOURCE_IND: // 34 PUCCH_RESOURCE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // defined in Subclause 9.2.3 TS 38.213 - // PUCCH_RESOURCE_IND points to PUCCH-ResourceId, but PUCCH-ResourceId is not defined yet - nr_pdci_info_extracted->pucch_resource_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pucch_resource_ind=%x\n",nr_pdci_info_extracted->pucch_resource_ind); - #endif - break; - - case PDSCH_TO_HARQ_FEEDBACK_TIME_IND: // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // defined in Subclause 9.2.3 TS 38.213 - // PDSCH_TO_HARQ_FEEDBACK_TIME_IND points to DL-data-DL-acknowledgement, but DL-data-DL-acknowledgement is not defined yet - nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind=%x\n",nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind); - #endif - break; - - case SRS_RESOURCE_IND: // 36 SRS_RESOURCE_IND: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->srs_resource_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_resource_ind=%x\n",nr_pdci_info_extracted->srs_resource_ind); - #endif - break; - case PRECOD_NBR_LAYERS: // 37 PRECOD_NBR_LAYERS: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->precod_nbr_layers = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->precod_nbr_layers=%x\n",nr_pdci_info_extracted->precod_nbr_layers); - #endif - break; - case ANTENNA_PORTS: // 38 ANTENNA_PORTS: (field defined for -,format0_1,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->antenna_ports = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->antenna_ports=%x\n",nr_pdci_info_extracted->antenna_ports); - #endif - break; - case TCI: // 39 TCI: (field defined for -,-,-,format1_1,-,-,-,-) - // 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits - nr_pdci_info_extracted->tci = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tci=%x\n",nr_pdci_info_extracted->tci); - #endif - break; - case SRS_REQUEST: // 40 SRS_REQUEST: (field defined for -,format0_1,-,format1_1,-,-,-,format2_3) - nr_pdci_info_extracted->srs_request = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_request=%x\n",nr_pdci_info_extracted->srs_request); - #endif - break; - case TPC_CMD: // 41 TPC_CMD: (field defined for -,-,-,-,-,-,-,format2_3) - nr_pdci_info_extracted->tpc_cmd = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_cmd=%x\n",nr_pdci_info_extracted->tpc_cmd); - #endif - break; - case CSI_REQUEST: // 42 CSI_REQUEST: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->csi_request = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->csi_request=%x\n",nr_pdci_info_extracted->csi_request); - #endif - break; - case CBGTI: // 43 CBGTI: (field defined for -,format0_1,-,format1_1,-,-,-,-) - // 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH - nr_pdci_info_extracted->cbgti = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgti=%x\n",nr_pdci_info_extracted->cbgti); - #endif - break; - case CBGFI: // 44 CBGFI: (field defined for -,-,-,format1_1,-,-,-,-) - // 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator - nr_pdci_info_extracted->cbgfi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgfi=%x\n",nr_pdci_info_extracted->cbgfi); - #endif - break; - case PTRS_DMRS: // 45 PTRS_DMRS: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->ptrs_dmrs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ptrs_dmrs=%x\n",nr_pdci_info_extracted->ptrs_dmrs); - #endif - break; - case BETA_OFFSET_IND: // 46 BETA_OFFSET_IND: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->beta_offset_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->beta_offset_ind=%x\n",nr_pdci_info_extracted->beta_offset_ind); - #endif - break; - case DMRS_SEQ_INI: // 47 DMRS_SEQ_INI: (field defined for -,format0_1,-,format1_1,-,-,-,-) - // 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise - nr_pdci_info_extracted->dmrs_seq_ini = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->dmrs_seq_ini); - #endif - break; - case UL_SCH_IND: // 48 UL_SCH_IND: (field defined for -,format0_1,-,-,-,-,-,-) - // value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH - nr_pdci_info_extracted->ul_sch_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->ul_sch_ind); - #endif - break; - - case PADDING_NR_DCI: // 49 PADDING_NR_DCI: (field defined for format0_0,-,format1_0,-,-,-,-,-) - // (Note 2) If DCI format 0_0 is monitored in common search space - nr_pdci_info_extracted->padding_nr_dci = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->padding=%x\n",nr_pdci_info_extracted->padding_nr_dci); - #endif - break; - - case SUL_IND_0_0: // 50 SUL_IND_0_0: (field defined for format0_0,-,-,-,-,-,-,-) - nr_pdci_info_extracted->sul_ind_0_0 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_0=%x\n",nr_pdci_info_extracted->sul_ind_0_0); - #endif - break; - - case RA_PREAMBLE_INDEX: // 51 RA_PREAMBLE_INDEX: (field defined for format0_0,-,-,-,-,-,-,-) - nr_pdci_info_extracted->ra_preamble_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ra_preamble_index=%x\n",nr_pdci_info_extracted->ra_preamble_index); - #endif - break; - - case SUL_IND_1_0: // 52 SUL_IND_1_0: (field defined for -,-,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->sul_ind_1_0 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_1_0=%x\n",nr_pdci_info_extracted->sul_ind_1_0); - #endif - break; - - case SS_PBCH_INDEX: // 53 SS_PBCH_INDEX: (field defined for -,-,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->ss_pbch_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ss_pbch_index=%x\n",nr_pdci_info_extracted->ss_pbch_index); - #endif - break; - - case PRACH_MASK_INDEX: // 54 PRACH_MASK_INDEX: (field defined for -,-,-,format1_0,-,-,-,-) - nr_pdci_info_extracted->prach_mask_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->prach_mask_index=%x\n",nr_pdci_info_extracted->prach_mask_index); - #endif - break; - - case RESERVED_NR_DCI: // 55 RESERVED_NR_DCI: (field defined for -,-,-,format1_0,-,-,-,-) - nr_pdci_info_extracted->reserved_nr_dci = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->reserved_nr_dci=%x\n",nr_pdci_info_extracted->reserved_nr_dci); - #endif - break; - - } - } - } - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Ending function nr_extract_dci_info()\n"); - #endif - return(1); -} - -#endif - -#ifdef NR_PDCCH_DCI_TOOLS - -int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - int frame, - uint8_t nr_tti_rx, - uint64_t dci_pdu[2], - uint16_t rnti, - uint8_t dci_length, - NR_DCI_format_t dci_format, - NR_DL_FRAME_PARMS *frame_parms, - PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES], - fapi_nr_dci_pdu_rel15_t *nr_dci_info_extracted) -{ - /* - * Note only format0_0 and format1_0 are implemented - */ - - uint8_t frame_type=frame_parms->frame_type; - uint8_t status=0; - - LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> dci_format=%d, rnti=%d, dci_length=%d, dci_pdu[0]=0x%lx, dci_pdu[1]=0x%lx\n",dci_format,rnti,dci_length,dci_pdu[0],dci_pdu[1]); - - memset(nr_dci_info_extracted,0,sizeof(*nr_dci_info_extracted)); - - LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d) \n",dci_format); - - status = nr_extract_dci_info(ue, - eNB_id, - frame_type, - dci_length, - rnti, - dci_pdu, - nr_dci_info_extracted,//&nr_dci_info_extracted, - dci_fields_sizes, - dci_format, - nr_tti_rx, - n_RB_ULBWP, - n_RB_DLBWP, - crc_scrambled_values); - - if(status == 0) { - LOG_W(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format); - return(-1); - } - - LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Ending function nr_extract_dci_info()\n"); - - //fill - - return(0); -} - -#endif - -uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx) -{ +uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx) { /* #ifdef DEBUG_DCI if (frame_parms->frame_type == TDD) @@ -1081,40 +68,37 @@ uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8 printf("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe); #endif */ - uint8_t ret = 255; uint8_t subframe = nr_tti_rx>>((int)(log2 (frame_parms->ttis_per_subframe))); AssertFatal(1==0,"Not ready for this ...\n"); if (frame_parms->frame_type == FDD) { - + ret = (((frame<<1)+nr_tti_rx)&7); } else { - } + if (ret == 255) { LOG_E(PHY, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", ret, frame, subframe); //mac_xface->macphy_exit("invalid harq_pid"); } + return ret; } - -uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n) -{ +uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n) { uint8_t ul_subframe = 255; AssertFatal(1==0,"Not ready for this\n"); } -uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n) -{ +uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n) { uint32_t ul_frame = 255; + AssertFatal(1==0,"Not ready for this\n"); } - diff --git a/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c index d976ec5a04..4d77854a70 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dmrs_nr.c @@ -258,7 +258,7 @@ uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position) { * *********************************************************************/ -uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { +uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) { uint16_t dmrs_idx; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index bff8a90b16..34fff12148 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -43,7 +43,8 @@ #include "executables/nr-uesoftmodem.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" -//#define DEBUG_DLSCH_DECODING +//#define DEBUG_DLSCH_DECODING 1 +//#define ENABLE_PHY_PAYLOAD_DEBUG 1 #define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX @@ -55,31 +56,46 @@ notifiedFIFO_elt_t *msgToPush; //extern double cpuf; -void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch) +void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL) { int i,r; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated + NR_UE_DLSCH_t *dlsch=*dlschptr; if (dlsch) { + if (N_RB_DL != 273) { + a_segments = a_segments*N_RB_DL; + a_segments = a_segments/273; + } + + uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + for (i=0; iMdlharq; i++) { if (dlsch->harq_processes[i]) { if (dlsch->harq_processes[i]->b) { - free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); + free16(dlsch->harq_processes[i]->b,dlsch_bytes); dlsch->harq_processes[i]->b = NULL; } - for (r=0; rharq_processes[i]->c[r],1056); dlsch->harq_processes[i]->c[r] = NULL; } - for (r=0; rharq_processes[i]->d[r]) { free16(dlsch->harq_processes[i]->d[r],(3*8448)*sizeof(short)); dlsch->harq_processes[i]->d[r] = NULL; } - for (r=0; r<(MAX_NUM_NR_DLSCH_SEGMENTS); r++) { + for (r=0; rharq_processes[i]->w[r]) { + free16(dlsch->harq_processes[i]->w[r],(3*8448)*sizeof(short)); + dlsch->harq_processes[i]->w[r] = NULL; + } + + for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r]){ nrLDPC_free_mem(dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]); dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL; @@ -102,25 +118,14 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint NR_UE_DLSCH_t *dlsch; uint8_t exit_flag = 0,i,r; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated - switch (N_RB_DL) { - case 6: - bw_scaling =16; - break; + if (N_RB_DL != 273) { + a_segments = a_segments*N_RB_DL; + a_segments = a_segments/273; + } - case 25: - bw_scaling =4; - break; - - case 50: - bw_scaling =2; - break; - - default: - bw_scaling =1; - break; - } + uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t)); @@ -139,15 +144,15 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint if (dlsch->harq_processes[i]) { memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t)); dlsch->harq_processes[i]->first_tx=1; - dlsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); + dlsch->harq_processes[i]->b = (uint8_t*)malloc16(dlsch_bytes); if (dlsch->harq_processes[i]->b) - memset(dlsch->harq_processes[i]->b,0,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); + memset(dlsch->harq_processes[i]->b,0,dlsch_bytes); else exit_flag=3; if (abstraction_flag == 0) { - for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(1056); @@ -162,6 +167,13 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint memset(dlsch->harq_processes[i]->d[r],0,(3*8448)*sizeof(short)); else exit_flag=2; + + dlsch->harq_processes[i]->w[r] = (short*)malloc16((3*8448)*sizeof(short)); + + if (dlsch->harq_processes[i]->w[r]) + memset(dlsch->harq_processes[i]->w[r],0,(3*8448)*sizeof(short)); + else + exit_flag=2; } } } else { @@ -174,7 +186,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint } printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag); - free_nr_ue_dlsch(dlsch); + free_nr_ue_dlsch(&dlsch,N_RB_DL); return(NULL); } @@ -231,7 +243,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_dec_params* p_decParams = &decParams; t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime =&procTime ; + + if (!harq_process) { + printf("dlsch_decoding.c: NULL harq_process pointer\n"); + return(dlsch->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]; @@ -244,18 +262,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint16_t nb_rb;// = 30; double Coderate;// = 0.0; - - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dl_config_pdu = &harq_process->dl_config_pdu; - uint8_t dmrs_Type = dl_config_pdu->dmrs_Type; + uint8_t dmrs_Type = harq_process->dmrsConfigType; AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type); uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; - uint8_t dmrs_TypeA_Position = dl_config_pdu->dmrs_TypeA_Position; - AssertFatal(dmrs_TypeA_Position == 2 || dmrs_TypeA_Position == 3,"Illegal dmrs_TypeA_Position %d\n",dmrs_TypeA_Position); - uint16_t dmrs_maxLength = dl_config_pdu->dmrs_maxLength; - AssertFatal(dmrs_maxLength == 1 || dmrs_maxLength == 2,"Illegal dmrs_maxLength %d\n",dmrs_maxLength); - uint16_t dmrs_AdditionalPosition = dl_config_pdu->dmrs_AdditionalPosition; - AssertFatal(dmrs_AdditionalPosition >= 0 && dmrs_AdditionalPosition <= 4,"Illegal dmrs_additional_symbols %d\n",dmrs_AdditionalPosition); - + uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos); + AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length); uint32_t i,j; @@ -269,11 +280,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations + 1); } - if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); - return(dlsch->max_ldpc_iterations + 1); - } - if (!frame_parms) { printf("dlsch_decoding.c: NULL frame_parms pointer\n"); return(dlsch->max_ldpc_iterations + 1); @@ -308,41 +314,26 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->trials[harq_process->round]++; - harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,dmrs_maxLength, harq_process->Nl); + uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, harq_process->Nl); A = harq_process->TBS; ret = dlsch->max_ldpc_iterations + 1; - - harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_maxLength, harq_process->Qm,harq_process->Nl); + dlsch->last_iteration_cnt = ret; + + harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl); G = harq_process->G; - LOG_I(PHY,"DLSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); + LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN); - if (harq_process->round == 0) { - // This is a new packet, so compute quantities regarding segmentation - harq_process->B = A+24; - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, // [hna] Z is Zc - &harq_process->F); + if ((harq_process->R)<1024) + Coderate = (float) (harq_process->R) /(float) 1024; + else + Coderate = (float) (harq_process->R) /(float) 2048; -#ifdef DEBUG_DLSCH_DECODING - if (!frame%100) - printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); -#endif - } - - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); - - p_decParams->Z = harq_process->Z; - //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); - - Coderate = (float) A /(float) G; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; @@ -375,6 +366,34 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } } + + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + if (A > 3824) + harq_process->B = A+24; + else + harq_process->B = A+16; + + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, // [hna] Z is Zc + &harq_process->F, + p_decParams->BG); + +#ifdef DEBUG_DLSCH_DECODING + if (!frame%100) + printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); +#endif + } + + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); + + p_decParams->Z = harq_process->Z; + //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); + //printf("coderate %f kc %d \n", Coderate, kc); p_decParams->numMaxIter = dlsch->max_ldpc_iterations; @@ -383,20 +402,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, err_flag = 0; r_offset = 0; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated - switch (frame_parms->N_RB_DL) { - case 106: - bw_scaling =2; - break; + if (nb_rb != 273) { + a_segments = a_segments*nb_rb; + a_segments = a_segments/273; + } - default: - bw_scaling =1; - break; - } - - if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling) { - LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling); + if (harq_process->C > a_segments) { + LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments); return((1+dlsch->max_ldpc_iterations)); } @@ -411,8 +425,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); - for (r=0; rC; r++) { //printf("start rx segment %d\n",r); @@ -424,11 +436,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN); + nr_deinterleaving_ldpc(E, harq_process->Qm, harq_process->w[r], // [hna] w is e dlsch_llr+r_offset); + vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT); //for (int i =0; i<16; i++) @@ -456,6 +470,12 @@ 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); + else + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C); + + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -465,7 +485,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->C, harq_process->rvidx, (harq_process->round==0)?1:0, - E)==-1) { + E, + harq_process->F, + Kr-harq_process->F-2*(p_decParams->Z))==-1) { vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); @@ -480,6 +502,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #endif } + //for (int i =0; i<16; i++) // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); @@ -488,12 +511,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING if (r==0) { write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); - write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); + write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); int i; - for (i=0;i<(3*8*Kr_bytes)+12;i++) + for (i=0;id[r][i]); printf("\n"); #endif @@ -503,8 +526,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // printf("done\n"); if (harq_process->C == 1){ - crc_type = CRC24_A; - length_dec = harq_process->B; + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; + + length_dec = harq_process->B; + } else{ crc_type = CRC24_B; @@ -525,12 +553,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //memset(pl,0,2*p_decParams->Z*sizeof(int8_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])); } - - for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) + // Kbytes_F = Kr_bytes - F>>3 + j+=(harq_process->F>>3); + // for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) + for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++,j++) { pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } @@ -541,25 +572,26 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN); - no_iteration_ldpc = nrLDPC_decoder(p_decParams, (int8_t*)&pl[0], llrProcBuf, p_nrLDPC_procBuf[r], p_procTime); - vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT); // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("\x1B[34m" "Segment %d CRC OK\n",r); + LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r); + //Temporary hack + no_iteration_ldpc = dlsch->max_ldpc_iterations; ret = no_iteration_ldpc; } else { - printf("\x1B[33m" "CRC NOK\n"); + LOG_D(PHY,"CRC NOK\n\033[0m"); ret = 1 + dlsch->max_ldpc_iterations; } + nb_total_decod++; if (no_iteration_ldpc > dlsch->max_ldpc_iterations){ nb_error_decod++; @@ -580,7 +612,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //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>3;k++) printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + 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 @@ -615,10 +647,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, frame_rx_prev = frame_rx_prev%1024; if (err_flag == 1) { -#if UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", +//#if UE_DEBUG_TRACE + LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); -#endif +//#endif harq_process->harq_ack.ack = 0; harq_process->harq_ack.harq_id = harq_pid; harq_process->harq_ack.send_harq_status = 1; @@ -639,10 +671,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return((1 + dlsch->max_ldpc_iterations)); } else { -#if UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); -#endif +//#if UE_DEBUG_TRACE + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", + phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); +//#endif harq_process->status = SCH_IDLE; harq_process->round = 0; @@ -650,7 +682,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->harq_ack.harq_id = harq_pid; harq_process->harq_ack.send_harq_status = 1; - //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", + //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", // phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); if(is_crnti) @@ -677,18 +709,32 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, for (r=0; rC; r++) { memcpy(harq_process->b+offset, - harq_process->c[r], - Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); + 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_DLSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + 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]); + + /*printf ("Printing payload bytes:"); + for (int i = 0; i < Kr_bytes; i++){ + printf("%d : %d \n", i, harq_process->b[i]); + }*/ +#endif + +#if defined(ENABLE_PHY_PAYLOAD_DEBUG) + if (frame%100 == 0){ + LOG_I (PHY, "Printing 10 first payload bytes at frame: %d ", frame); + for (int i = 0; i <10 ; i++){ //Kr_bytes + LOG_I(PHY, "[%d] : %x ", i, harq_process->b[i]); + } + } #endif } @@ -724,14 +770,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, uint32_t A,E; uint32_t G; uint32_t ret,offset; - //short dummy_w[MAX_NUM_DLSCH_SEGMENTS][3*(8448+64)]; uint32_t r,r_offset=0,Kr=8424,Kr_bytes,err_flag=0,K_bytes_F; uint8_t crc_type; //UE_rxtx_proc_t *proc = &phy_vars_ue->proc; int32_t no_iteration_ldpc,length_dec; /*uint8_t C; uint8_t Qm; - uint8_t Nl; uint8_t r_thread; uint32_t Er, Gp,GpmodC;*/ t_nrLDPC_dec_params decParams; @@ -739,22 +783,26 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime =&procTime ; int8_t llrProcBuf[OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); + if (!harq_process) { + printf("dlsch_decoding.c: NULL harq_process pointer\n"); + return(dlsch->max_ldpc_iterations); + } t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0]; - + uint8_t Nl=4; int16_t z [68*384]; int8_t l [68*384]; //__m128i l; int16_t inv_d [68*384]; //int16_t *p_invd =&inv_d; uint8_t kb, kc; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; double Coderate = 0.0; - nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config; - uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; - uint8_t nb_re_dmrs = (dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; - uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value; + nfapi_nr_dl_config_dlsch_pdu_rel15_t *dl_config_pdu = &harq_processes[harq_pid]->dl_config_pdu + uint8_t dmrs_type = dl_config_pdu->dmrsConfigType; + uint8_t nb_re_dmrs = (dmrs_type==1)?6:4; + uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); uint32_t i,j; @@ -769,10 +817,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return(dlsch->max_ldpc_iterations); } - if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); - return(dlsch->max_ldpc_iterations); - } + if (!frame_parms) { printf("dlsch_decoding.c: NULL frame_parms pointer\n"); @@ -805,7 +850,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, nb_rb = harq_process->nb_rb; harq_process->trials[harq_process->round]++; - harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl); + uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl); A = harq_process->TBS; @@ -815,7 +862,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, G = harq_process->G; - LOG_I(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); + LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); proc->decoder_main_available = 1; @@ -825,22 +872,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, // printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi); - if (harq_process->round == 0) { - // This is a new packet, so compute quantities regarding segmentation - harq_process->B = A+24; - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); + if ((harq_process->R)<1024) + Coderate = (float) (harq_process->R) /(float) 1024; + else + Coderate = (float) (harq_process->R) /(float) 2048; - p_decParams->Z = harq_process->Z; - - } - - Coderate = (float) A /(float) G; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; @@ -873,6 +909,26 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } } + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + if (A > 3824) + harq_process->B = A+24; + else + harq_process->B = A+16; + + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, + &harq_process->F, + p_decParams->BG); + + p_decParams->Z = harq_process->Z; + + } + //printf("coderate %f kc %d \n", Coderate, kc); p_decParams->numMaxIter = dlsch->max_ldpc_iterations; p_decParams->outMode= 0; @@ -880,20 +936,15 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, err_flag = 0; r_offset = 0; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated - switch (frame_parms->N_RB_DL) { - case 106: - bw_scaling =2; - break; + if (nb_rb != 273) { + a_segments = a_segments*nb_rb; + a_segments = a_segments/273; + } - default: - bw_scaling =1; - break; - } - - if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) { - LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_DLSCH_SEGMENTS/bw_scaling); + if (harq_process->C > a_segments) { + LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments); return((1+dlsch->max_ldpc_iterations)); } #ifdef DEBUG_DLSCH_DECODING @@ -951,8 +1002,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, Kr_bytes = Kr>>3; K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); - E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); /* @@ -970,7 +1019,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING 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); + printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); #endif #if UE_TIMING_TRACE @@ -993,6 +1042,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, harq_process->round); #endif + // for tbslbrm calculation according to 5.4.2.1 of 38.212 + if (harq_process->Nl < Nl) + Nl = harq_process->Nl; + + Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -1002,7 +1057,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, harq_process->C, harq_process->rvidx, (harq_process->round==0)?1:0, - E)==-1) { + E, + harq_process->F, + Kr-harq_process->F-2*(p_decParams->Z))==-1) { #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); #endif @@ -1023,7 +1080,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset); #endif #ifdef DEBUG_DLSCH_DECODING @@ -1033,7 +1090,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + printf("decoder input(segment %u) :",r); for (int i=0;i<(3*8*Kr_bytes);i++) printf("%d : %d\n",i,harq_process->d[r][i]); printf("\n"); @@ -1045,7 +1102,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, // printf("done\n"); if (harq_process->C == 1){ - crc_type = CRC24_A; + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; + length_dec = harq_process->B; } else{ @@ -1057,7 +1118,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if (err_flag == 0) { /* - LOG_I(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", + LOG_D(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations); */ @@ -1107,7 +1168,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); + printf("Segment %u CRC OK\n",r); ret = 2; } else { @@ -1116,7 +1177,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, } //if (!nb_total_decod%10000){ - printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); + printf("Error number of iteration LPDC %d %lu/%lu \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); //} //else @@ -1170,7 +1231,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if (err_flag == 1) { #if UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); #endif harq_process->harq_ack.ack = 0; @@ -1194,7 +1255,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return((1+dlsch->max_ldpc_iterations)); } else { #if UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d\n", phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); #endif @@ -1257,7 +1318,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_DLSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + 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", @@ -1296,7 +1357,7 @@ void *nr_dlsch_decoding_process(void *arg) int16_t inv_d [68*384]; int16_t *p_invd =&inv_d; uint8_t kb, kc; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; //to update double Coderate = 0.0; @@ -1324,7 +1385,6 @@ void *nr_dlsch_decoding_process(void *arg) uint32_t A,E; uint32_t G; uint32_t ret,offset; -// short dummy_w[MAX_NUM_DLSCH_SEGMENTS][3*(8448+64)]; uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bytes_F; uint8_t crc_type; uint8_t C,Cprime; @@ -1336,8 +1396,8 @@ void *nr_dlsch_decoding_process(void *arg) int harq_pid = proc->harq_pid; llr8_flag1 = proc->llr8_flag; int frame = proc->frame_rx; - int slot = proc->nr_tti_rx; - r = proc->num_seg; + int slot = proc->nr_tti_rx; + r = proc->num_seg; NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0]; NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; @@ -1345,7 +1405,7 @@ void *nr_dlsch_decoding_process(void *arg) //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r]; nb_symb_sch = harq_process->nb_symbols; - printf("dlsch decoding process frame %d slot %d segment %d r %d nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); + printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); /* @@ -1365,7 +1425,9 @@ void *nr_dlsch_decoding_process(void *arg) harq_process->trials[harq_process->round]++; - harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl); + uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs + + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl); A = harq_process->TBS; //2072 for QPSK 1/3 @@ -1375,25 +1437,13 @@ void *nr_dlsch_decoding_process(void *arg) harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl); G = harq_process->G; - LOG_I(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); + LOG_D(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); - - if (harq_process->round == 0) { - // This is a new packet, so compute quantities regarding segmentation - harq_process->B = A+24; + if ((harq_process->R)<1024) + Coderate = (float) (harq_process->R) /(float) 1024; + else + Coderate = (float) (harq_process->R) /(float) 2048; - nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); - p_decParams->Z = harq_process->Z; - - } - - Coderate = (float) A /(float) G; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; @@ -1424,7 +1474,29 @@ void *nr_dlsch_decoding_process(void *arg) p_decParams->R = 89; kc = 27; } - } + } + + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + if (A > 3824) + harq_process->B = A+24; + else + harq_process->B = A+16; + + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, + &harq_process->F, + p_decParams->BG); + + p_decParams->Z = harq_process->Z; + + } + + p_decParams->numMaxIter = dlsch->max_ldpc_iterations; p_decParams->outMode= 0; @@ -1439,20 +1511,15 @@ void *nr_dlsch_decoding_process(void *arg) //r_offset = 0; /* - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated - switch (frame_parms->N_RB_DL) { - case 106: - bw_scaling =2; - break; + if (nb_rb != 273) { + a_segments = a_segments*nb_rb; + a_segments = a_segments/273; + } - default: - bw_scaling =1; - break; - } - - if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) { - LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_DLSCH_SEGMENTS/bw_scaling); + if (harq_process->C > a_segments) { + LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments); return((1+dlsch->max_ldpc_iterations)); }*/ #ifdef DEBUG_DLSCH_DECODING @@ -1484,9 +1551,7 @@ void *nr_dlsch_decoding_process(void *arg) Kr_bytes = Kr>>3; K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); - - E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); + E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); #if UE_TIMING_TRACE start_meas(dlsch_deinterleaving_stats); @@ -1498,7 +1563,7 @@ void *nr_dlsch_decoding_process(void *arg) #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); #endif #if UE_TIMING_TRACE @@ -1521,6 +1586,11 @@ void *nr_dlsch_decoding_process(void *arg) harq_process->round); #endif + if (Nl<4) + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C); + else + Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C); + if (nr_rate_matching_ldpc_rx(Ilbrm, Tbslbrm, p_decParams->BG, @@ -1530,7 +1600,9 @@ void *nr_dlsch_decoding_process(void *arg) harq_process->C, harq_process->rvidx, (harq_process->round==0)?1:0, - E)==-1) { + E, + harq_process->F, + Kr-harq_process->F-2*(p_decParams->Z))==-1) { #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); #endif @@ -1554,7 +1626,7 @@ void *nr_dlsch_decoding_process(void *arg) write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %d) :",r); + 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"); @@ -1565,7 +1637,11 @@ void *nr_dlsch_decoding_process(void *arg) memset(harq_process->c[r],0,Kr_bytes); if (harq_process->C == 1){ - crc_type = CRC24_A; + if (A > 3824) + crc_type = CRC24_A; + else + crc_type = CRC16; + length_dec = harq_process->B; } else{ @@ -1575,7 +1651,7 @@ void *nr_dlsch_decoding_process(void *arg) if (err_flag == 0) { /* - LOG_I(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", + LOG_D(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations); */ @@ -1587,11 +1663,11 @@ void *nr_dlsch_decoding_process(void *arg) start_meas(dlsch_turbo_decoding_stats); #endif // LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); - +/* for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ inv_d[cnt] = (1)*harq_process->d[r][cnt]; } - +*/ memset(pv,0,2*p_decParams->Z*sizeof(int16_t)); //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); @@ -1619,16 +1695,16 @@ void *nr_dlsch_decoding_process(void *arg) // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); + LOG_D(PHY,"Segment %u CRC OK\n",r); ret = 2; } else { - printf("CRC NOK\n"); + LOG_D(PHY,"Segment %u CRC NOK\n",r); ret = 1+dlsch->max_ldpc_iterations; } if (no_iteration_ldpc > 10) - printf("Error number of iteration LPDC %d\n", no_iteration_ldpc); + LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc); //else //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 53c6615dbd..8bf0cb66c4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -101,16 +101,16 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, int16_t **llr_layers); int nr_rx_pdsch(PHY_VARS_NR_UE *ue, - PDSCH_t type, - unsigned char eNB_id, - unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference - uint32_t frame, - uint8_t nr_tti_rx, - unsigned char symbol, - unsigned char first_symbol_flag, - RX_type_t rx_type, - unsigned char i_mod, - unsigned char harq_pid) + PDSCH_t type, + unsigned char eNB_id, + unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference + uint32_t frame, + uint8_t nr_tti_rx, + unsigned char symbol, + unsigned char first_symbol_flag, + RX_type_t rx_type, + unsigned char i_mod, + unsigned char harq_pid) { NR_UE_COMMON *common_vars = &ue->common_vars; @@ -151,7 +151,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //int16_t *pllr_symbol_cw1_deint; uint32_t llr_offset_symbol; //uint16_t bundle_L = 2; - uint8_t l0 =2, pilots=0; + uint8_t pilots=0; uint16_t n_tx=1, n_rx=1; int32_t median[16]; uint32_t len; @@ -176,7 +176,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; - dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm(dlsch[0]->harq_processes[harq_pid]->mcs, 1);; + dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); + dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", @@ -233,7 +234,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, start_rb = dlsch0_harq->start_rb; nb_rb_pdsch = dlsch0_harq->nb_rb; - l0 = dlsch0_harq->start_symbol; + int lbar; DevAssert(dlsch0_harq); round = dlsch0_harq->round; @@ -275,7 +276,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } #if UE_TIMING_TRACE - if(symbol > ue->frame_parms.symbols_per_tti>>1) + if(symbol > ue->frame_parms.symbols_per_slot>>1) { slot = 1; } @@ -285,7 +286,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, printf("Demod dlsch0_harq->pmi_alloc %d\n", dlsch0_harq->pmi_alloc); #endif - pilots = (symbol==l0) ? 1 : 0; + pilots = ((1<dlDmrsSymbPos)>0 ? 1 : 0; if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) { #ifdef DEBUG_DLSCH_MOD @@ -296,19 +297,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #endif nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, - pdsch_vars[eNB_id]->dl_ch_estimates, - pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id]->pmi_ext, - symbol, - pilots, - start_rb, - nb_rb_pdsch, - nr_tti_rx, - ue->high_speed_flag, - frame_parms, - dlsch0_harq->mimo_mode); + pdsch_vars[eNB_id]->dl_ch_estimates, + pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + pdsch_vars[eNB_id]->pmi_ext, + symbol, + pilots, + start_rb, + nb_rb_pdsch, + nr_tti_rx, + ue->high_speed_flag, + frame_parms, + dlsch0_harq->mimo_mode); #ifdef DEBUG_DLSCH_MOD printf("dlsch: using pmi %lx, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); for (rb=0;rbcurrent_thread_id[nr_tti_rx]); nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, - pdsch_vars[eNB_id]->dl_ch_estimates, - pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id]->pmi_ext, - symbol, - pilots, - start_rb, - nb_rb_pdsch, - nr_tti_rx, - ue->high_speed_flag, - frame_parms); + pdsch_vars[eNB_id]->dl_ch_estimates, + pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + pdsch_vars[eNB_id]->pmi_ext, + symbol, + pilots, + start_rb, + nb_rb_pdsch, + nr_tti_rx, + ue->high_speed_flag, + frame_parms); } /*else if(beamforming_mode>7) { LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); @@ -374,16 +375,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return(-1); } - len = (symbol==l0)? (nb_rb*6):(nb_rb*12); + len = (pilots==1)? (nb_rb*6):(nb_rb*12); #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,nr_tti_rx,slot, - symbol,ue->high_speed_flag,type,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", + frame,nr_tti_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,nr_tti_rx,slot,symbol, - ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n", + frame,nr_tti_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -394,11 +395,11 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, n_rx = frame_parms->nb_antennas_rx; nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - dlsch, - symbol, - pilots, - nb_rb); + frame_parms, + dlsch, + symbol, + pilots, + nb_rb); #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); @@ -426,7 +427,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, for (aarx=0;aarxnb_antennas_rx;aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); - pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1; + pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { @@ -647,13 +648,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif #if UE_TIMING_TRACE + start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); #endif //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol); // compute LLRs // -> // compute @pointer where llrs should filled for this ofdm-symbol - pdsch_vars[eNB_id]->llr_offset[l0-1] = 0; + if (first_symbol_flag==1) pdsch_vars[eNB_id]->llr_offset[symbol-1] = 0; llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1]; //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0]; //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1]; @@ -964,7 +966,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, break; } if (dlsch1_harq) { - switch (nr_get_Qm(dlsch1_harq->mcs, 1)) { + switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) { case 2 : if (rx_type==rx_standard) { nr_dlsch_qpsk_llr(frame_parms, @@ -1064,9 +1066,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if T_TRACER T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame%1024), T_INT(nr_tti_rx), T_INT(nb_rb), - T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_tti), + T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_slot), T_BUFFER(&pdsch_vars[eNB_id]->rxdataF_comp0[eNB_id][0], - 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2)); + 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2)); #endif return(0); @@ -1787,11 +1789,11 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, - NR_DL_FRAME_PARMS *frame_parms, - NR_UE_DLSCH_t **dlsch_ue, - uint8_t symbol, - uint8_t pilots, - unsigned short nb_rb) + NR_DL_FRAME_PARMS *frame_parms, + NR_UE_DLSCH_t **dlsch_ue, + uint8_t symbol, + uint8_t pilots, + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) @@ -1807,7 +1809,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, // Determine scaling amplitude based the symbol -ch_amp = 1024*8; //((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); + ch_amp = 1024*8; //((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); @@ -2379,10 +2381,13 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned char j=0; - k = frame_parms->first_carrier_offset + 12*start_rb; + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, + "nushift %d is illegal\n",frame_parms->nushift); for (aarx=0; aarxnb_antennas_rx; aarx++) { + k = frame_parms->first_carrier_offset + 12*start_rb; + if (high_speed_flag == 1) dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; else @@ -2393,65 +2398,43 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; - //printf("extract single addr %p pilots %d symbol %d, l %d RB_DL %d nushift %d k %d\n", rxF, pilots, symbol, l, frame_parms->N_RB_DL,frame_parms->nushift,k); - - //if ((frame_parms->N_RB_DL&1) == 0){ // even number of RBs - - for (rb = start_rb; rb < nb_rb_pdsch + start_rb; rb++) { - - // For second half of RBs skip DC carrier - if (k>=frame_parms->ofdm_symbol_size) { - rxF = &rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))]; - k=k-(frame_parms->ofdm_symbol_size); + for (rb = 0; rb < nb_rb_pdsch; rb++) { + if (k>frame_parms->ofdm_symbol_size) { + k = k-frame_parms->ofdm_symbol_size; + rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; } - - //*pmi_ext = (pmi>>((rb>>2)<<1))&3; - //memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - - /* - printf("rb %d\n",rb); - for (i=0;i<12;i++) - printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]); - printf("\n"); - */ - if (pilots==0) { - for (i=0; i<12; i++) { - rxF_ext[i]=rxF[i]; - dl_ch0_ext[i]=dl_ch0[i]; - /*printf("rb %ld %p: (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF, - ((short*)&rxF[i])[0],((short*)&rxF[i])[1]); - printf("rb %ld %p: dl_ch (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF, - ((short*)&dl_ch0[i])[0],((short*)&dl_ch0[i])[1]); - printf("re count %d\n",rb*12+i);*/ - } - - dl_ch0_ext+=12; - rxF_ext+=12; - } else { - j=0; - - for (i=0; i<12; i++) { - if ((i&1)!=frame_parms->nushift){ - rxF_ext[j]=rxF[i]; - //printf("extract rb %d, re %d => rxF (%d,%d) rxF ext (%d,%d) addr %p\n",rb,i,*(short *)&rxF[i],*(1+(short*)&rxF[i]),*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]),rxF_ext); - dl_ch0_ext[j]=dl_ch0[i]; - //printf("rb %ld %p: dl_ch (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF, - //((short*)&dl_ch0[i])[0],((short*)&dl_ch0[i])[1]); - j++; - } - } - - dl_ch0_ext+=6; - rxF_ext+=6; - } - - dl_ch0+=12; - rxF+=12; - k+=12; + if (pilots==0) { + memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext)); + memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext)); + dl_ch0_ext+=12; + rxF_ext+=12; + } else { + j=0; + + for (i = (1-frame_parms->nushift); + i<12; + i+=2) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + + + dl_ch0_ext+=6; + rxF_ext+=6; } + + dl_ch0+=12; + rxF+=12; + k+=12; + if (k>=frame_parms->ofdm_symbol_size) { + k=k-(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; + } + } } - - + + return(nb_rb_pdsch/frame_parms->nb_antennas_rx); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index fc4fff1c40..059bef61b5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -215,7 +215,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, int rx_power=0; //aarx, //nfapi_nr_config_request_t* config; - int n_ssb_crb=(fp->N_RB_DL-20); + int n_ssb_crb=(fp->N_RB_DL-20)>>1; + // First try TDD normal prefix, mu 1 fp->Ncp=NORMAL; fp->frame_type=TDD; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index cac9ae92ac..dd04104edd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -71,7 +71,7 @@ uint16_t nr_pbch_extract(int **rxdataF, rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; rxF_ext = &rxdataF_ext[aarx][symbol*20*12]; #ifdef DEBUG_PBCH - printf("extract_rbs (nushift %d): rx_offset=%d, symbol %d\n",frame_parms->nushift, + printf("extract_rbs (nushift %d): rx_offset=%d, symbol %u\n",frame_parms->nushift, (rx_offset + ((symbol+s_offset)*(frame_parms->ofdm_symbol_size))),symbol); int16_t *p = (int16_t *)rxF; @@ -93,7 +93,7 @@ uint16_t nr_pbch_extract(int **rxdataF, (i!=(nushiftmod4+8))) { rxF_ext[j]=rxF[rx_offset]; #ifdef DEBUG_PBCH - printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(9*rb) + j, + printf("rxF ext[%d] = (%d,%d) rxF [%u]= (%d,%d)\n",(9*rb) + j, ((int16_t *)&rxF_ext[j])[0], ((int16_t *)&rxF_ext[j])[1], rx_offset, @@ -116,7 +116,7 @@ uint16_t nr_pbch_extract(int **rxdataF, (i!=(nushiftmod4+8))) { rxF_ext[j]=rxF[rx_offset]; #ifdef DEBUG_PBCH - printf("rxF ext[%d] = (%d,%d) rxF [%d]= (%d,%d)\n",(rb<4) ? (9*rb) + j : (9*(rb-12))+j, + printf("rxF ext[%d] = (%d,%d) rxF [%u]= (%d,%d)\n",(rb<4) ? (9*rb) + j : (9*(rb-12))+j, ((int16_t *)&rxF_ext[j])[0], ((int16_t *)&rxF_ext[j])[1], rx_offset, @@ -425,11 +425,12 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, int max_h=0; int symbol; //uint8_t pbch_a[64]; - uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32); +//FT ?? cppcheck doesn't like pbch_a allocation because of line 525..and i don't get what this variable is for.. +//uint8_t *pbch_a = malloc(sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); //uint32_t pbch_a_prime; int16_t *pbch_e_rx; uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output; - uint8_t nushift,n_hf,ssb_index; + uint8_t nushift,ssb_index; uint16_t M; uint8_t Lmax=frame_parms->Lmax; //uint16_t crc; @@ -438,7 +439,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, //uint8_t decoderListSize = 8, pathMetricAppr = 0; //time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving; //time_stats_t path_metric,sorting,update_LLR; - memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); +// FT ?? cppcheck fix memset(&pbch_a[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS); //printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell); pbch_e_rx = &nr_ue_pbch_vars->llr[0]; @@ -522,7 +523,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #endif pbch_e_rx = nr_ue_pbch_vars->llr; //demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e; - pbch_a = nr_ue_pbch_vars->pbch_a; +// FT?? cppcheck fix - pbch_a = nr_ue_pbch_vars->pbch_a; #ifdef DEBUG_PBCH //pbch_e_rx = &nr_ue_pbch_vars->llr[0]; short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][20*12]); @@ -537,8 +538,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041; nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0); //polar decoding de-rate matching - const t_nrPolar_params *currentPtr = nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL); - decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&nr_ue_pbch_vars->pbch_a_prime,currentPtr); + const t_nrPolar_params *currentPtr = nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL,1,&ue->polarList); + decoderState = polar_decoder_int16(pbch_e_rx,(uint64_t *)&nr_ue_pbch_vars->pbch_a_prime,0,currentPtr); if(decoderState) return(decoderState); @@ -577,7 +578,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, for (int i=0; i<3; i++) decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff); - n_hf = ((nr_ue_pbch_vars->xtra_byte>>4)&0x01); // computing the half frame index from the extra byte + frame_parms->half_frame_bit = ((nr_ue_pbch_vars->xtra_byte>>4)&0x01); // computing the half frame index from the extra byte ssb_index = i_ssb; // ssb index corresponds to i_ssb for Lmax = 4,8 if (Lmax == 64) { // for Lmax = 64 ssb index 4th,5th and 6th bits are in extra byte @@ -585,7 +586,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i)); } - ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index, n_hf); + ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index); #ifdef DEBUG_PBCH printf("xtra_byte %x payload %x\n", nr_ue_pbch_vars->xtra_byte, payload); @@ -611,7 +612,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, rx_ind.rx_indication_body[0].mib_pdu.ssb_index = i_ssb; // confirm with TCL rx_ind.rx_indication_body[0].mib_pdu.ssb_length = Lmax; // confirm with TCL rx_ind.rx_indication_body[0].mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL - rx_ind.number_pdus = 1; + rx_ind.number_pdus = 1; //rx_ind.number_pdus++; if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index e0119ea7ea..2991ebf3d6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -47,7 +47,8 @@ \brief This function frees memory allocated for a particular DLSCH at UE @param dlsch Pointer to DLSCH to be removed */ -void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch); +void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlsch,uint8_t N_RB_DL); + /** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag) \brief This function allocates structures for a particular DLSCH at UE @@ -61,7 +62,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch); NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag); -void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch); +void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch,unsigned char N_RB_UL); NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag); @@ -1055,18 +1056,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, NR_DL_FRAME_PARMS* frame_parms, uint8_t harq_pid); -/*! \brief Fill up NR_UE_ULSCH_t and NR_UL_UE_HARQ_t structs - @param[in] UE, Pointer to PHY_VARS_NR_UE struct - @param[in] thread_id, thread id - @param[in] gNB_id, gNB id - @param[in] harq_pid, harq id -*/ - -int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE, - uint8_t thread_id, - int gNB_id, - unsigned char harq_pid); - /*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1 @param[in] in, Pointer to input bits @param[in] size, of input bits @@ -1076,7 +1065,7 @@ int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE, */ void nr_pusch_codeword_scrambling(uint8_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out); @@ -1088,19 +1077,21 @@ void nr_pusch_codeword_scrambling(uint8_t *in, - transform precoding */ -uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, +void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, unsigned char harq_pid, uint8_t slot, uint8_t thread_id, - int eNB_id); + int gNB_id); /** \brief This function does IFFT for PUSCH */ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, + uint8_t harq_pid, uint8_t slot, - uint8_t Nl, + uint8_t thread_id, + uint8_t gNB_id, NR_DL_FRAME_PARMS *frame_parms); @@ -1123,6 +1114,7 @@ void *nr_dlsch_decoding_2thread0(void *arg); void *nr_dlsch_decoding_2thread1(void *arg); + void nr_dlsch_unscrambling(int16_t* llr, uint32_t size, uint8_t q, @@ -1134,17 +1126,10 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue, PDSCH_t dlsch_id, uint8_t eNB_id); - int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, uint32_t frame, - uint8_t nr_tti_rx, - uint8_t eNB_id, - MIMO_mode_t mimo_mode, - uint32_t high_speed_flag, - uint8_t is_secondary_ue, - int nb_coreset_active, - uint16_t symbol_mon, - NR_SEARCHSPACE_TYPE_t searchSpaceType); + uint32_t slot); + /*! \brief Extract PSS and SSS resource elements @param phy_vars_ue Pointer to UE variables @@ -1554,10 +1539,9 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi); -void pdcch_unscrambling(NR_DL_FRAME_PARMS *frame_parms, - uint8_t subframe, - int8_t* llr, - uint32_t length); +void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t slot, + int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id); + @@ -1721,46 +1705,14 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms, uint8_t n_ra_prboffset, uint8_t tdd_mapindex, uint16_t Nf); -void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8_t nr_tti_rx, - int16_t *z, uint32_t length, uint16_t pdcch_DMRS_scrambling_id, int do_common); - uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset); -uint8_t nr_dci_decoding_procedure(int s, - int p, - PHY_VARS_NR_UE *ue, - NR_DCI_ALLOC_t *dci_alloc, - NR_SEARCHSPACE_TYPE_t searchSpacetype, - int16_t eNB_id, - uint8_t nr_tti_rx, - uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - crc_scrambled_t *crc_scrambled, - format_found_t *format_found, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]); +uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, + int frame, + int slot, + fapi_nr_dci_indication_t *dci_ind); -int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - int frame, - uint8_t nr_tti_rx, - uint64_t dci_pdu[2], - uint16_t rnti, - uint8_t dci_length, - NR_DCI_format_t dci_format, - NR_UE_PDCCH *pdcch_vars, - NR_UE_PDSCH *pdsch_vars, - NR_UE_DLSCH_t **dlsch, - NR_UE_ULSCH_t *ulsch, - NR_DL_FRAME_PARMS *frame_parms, - PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - uint8_t beamforming_mode, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES], - NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted); /** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs - RB extraction (signal and channel estimates) @@ -1804,22 +1756,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); -int nr_extract_dci_info(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - lte_frame_type_t frame_type, - uint8_t dci_length, - uint16_t rnti, - uint64_t dci_pdu[2], - fapi_nr_dci_pdu_rel15_t *nr_pdci_info_extracted, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - NR_DCI_format_t dci_format, - uint8_t nr_tti_rx, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]); + int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ); void *dlsch_thread(void *arg); /**@}*/ #endif + diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 7b65140612..f976da0a3a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -127,9 +127,9 @@ typedef struct { /// LDPC-code outputs uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; /// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17) - uint8_t e[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); + uint8_t *e; /// Rate matching (Interleaving) outputs (TS 36.212 V15.4.0, Sec 5.4.2.2 p. 30) - uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); + uint8_t *f; /// Number of code segments uint32_t C; /// Number of bits in code segments @@ -159,10 +159,6 @@ typedef struct { } NR_UL_UE_HARQ_t; typedef struct { - /// Current Number of Symbols - uint8_t Nsymb_pusch; - /// Nsc_pusch, number of allocated subcarriers for ULSCH - uint16_t Nsc_pusch; /// number of DMRS resource elements uint8_t nb_re_dmrs; /// DMRS length @@ -259,8 +255,6 @@ typedef struct { uint8_t DCINdi; /// DLSCH status flag indicating SCH_status_t status; - /// Dynamic Configuration from FAPI - nfapi_nr_dl_config_dlsch_pdu_rel15_t dl_config_pdu; /// Transport block size uint32_t TBS; /// The payload + CRC size in bits @@ -271,22 +265,26 @@ typedef struct { uint8_t *c[MAX_NUM_NR_DLSCH_SEGMENTS]; /// Index of current HARQ round for this DLSCH uint8_t round; + /// MCS table for this DLSCH + uint8_t mcs_table; /// MCS format for this DLSCH uint8_t mcs; /// Qm (modulation order) for this DLSCH uint8_t Qm; + /// target code rate R x 1024 + uint16_t R; /// Redundancy-version of the current sub-frame uint8_t rvidx; /// MIMO mode for this DLSCH MIMO_nrmode_t mimo_mode; /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - int16_t w[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; + int16_t *w[MAX_NUM_NR_DLSCH_SEGMENTS]; /// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) //double w_abs[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) int16_t *d[MAX_NUM_NR_DLSCH_SEGMENTS]; /// LDPC processing buffers - t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_DLSCH_SEGMENTS]; + t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_DLSCH_SEGMENTS]; /// Number of code segments uint32_t C; /// Number of bits in code segments @@ -301,12 +299,20 @@ typedef struct { int8_t delta_PUCCH; /// Number of soft channel bits uint32_t G; + /// Start PRB of BWP + uint16_t BWPStart; + /// Number of PRBs in BWP + uint16_t BWPSize; /// Current Number of RBs uint16_t nb_rb; /// Starting RB number uint16_t start_rb; /// Number of Symbols uint16_t nb_symbols; + /// DMRS symbol positions + uint16_t dlDmrsSymbPos; + /// DMRS Configuration Type + uint8_t dmrsConfigType; /// Starting Symbol number uint16_t start_symbol; /// Current subband PMI allocation diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 5c8493c370..334c8dfdd4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -42,28 +42,44 @@ -void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) +void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch,unsigned char N_RB_UL) { - int i; - int r; + int i, r; if (ulsch) { #ifdef DEBUG_ULSCH_FREE printf("Freeing ulsch %p\n",ulsch); #endif + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated + + if (N_RB_UL != 273) { + a_segments = a_segments*N_RB_UL; + a_segments = a_segments/273; + } + + uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment + for (i=0; iharq_processes[i]) { if (ulsch->harq_processes[i]->a) { - free16(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES); + free16(ulsch->harq_processes[i]->a,ulsch_bytes); ulsch->harq_processes[i]->a = NULL; } if (ulsch->harq_processes[i]->b) { - free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES); + free16(ulsch->harq_processes[i]->b,ulsch_bytes); ulsch->harq_processes[i]->b = NULL; } - for (r=0; rharq_processes[i]->e) { + free16(ulsch->harq_processes[i]->e,14*N_RB_UL*12*8); + ulsch->harq_processes[i]->e = NULL; + } + if (ulsch->harq_processes[i]->f) { + free16(ulsch->harq_processes[i]->f,14*N_RB_UL*12*8); + ulsch->harq_processes[i]->f = NULL; + } + for (r=0; rharq_processes[i]->c[r]) { free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); ulsch->harq_processes[i]->c[r] = NULL; @@ -87,24 +103,20 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) } - -NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag) +NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, + int number_of_harq_pids, + uint8_t abstraction_flag) { - NR_UE_ULSCH_t *ulsch; unsigned char exit_flag = 0,i,r; - unsigned char bw_scaling =1; + uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated - switch (N_RB_UL) { + if (N_RB_UL != 273) { + a_segments = a_segments*N_RB_UL; + a_segments = a_segments/273; + } - case 106: - bw_scaling =2; - break; - - default: - bw_scaling =1; - break; - } + uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment ulsch = (NR_UE_ULSCH_t *)malloc16(sizeof(NR_UE_ULSCH_t)); @@ -124,25 +136,25 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u // printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]); if (ulsch->harq_processes[i]) { memset(ulsch->harq_processes[i], 0, sizeof(NR_UL_UE_HARQ_t)); - ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); - ulsch->harq_processes[i]->a = (unsigned char*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->b = (uint8_t*)malloc16(ulsch_bytes); + ulsch->harq_processes[i]->a = (unsigned char*)malloc16(ulsch_bytes); if (ulsch->harq_processes[i]->a) { - bzero(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + bzero(ulsch->harq_processes[i]->a,ulsch_bytes); } else { printf("Can't allocate PDU\n"); exit_flag=1; } if (ulsch->harq_processes[i]->b) - bzero(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + bzero(ulsch->harq_processes[i]->b,ulsch_bytes); else { LOG_E(PHY,"Can't get b\n"); exit_flag=1; } if (abstraction_flag==0) { - for (r=0; rharq_processes[i]->c[r] = (uint8_t*)malloc16(8448); ulsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output @@ -160,6 +172,20 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u exit_flag=2; } } + ulsch->harq_processes[i]->e = (uint8_t*)malloc16(14*N_RB_UL*12*8); + if (ulsch->harq_processes[i]->e) { + bzero(ulsch->harq_processes[i]->e,14*N_RB_UL*12*8); + } else { + printf("Can't get e\n"); + exit_flag=1; + } + ulsch->harq_processes[i]->f = (uint8_t*)malloc16(14*N_RB_UL*12*8); + if (ulsch->harq_processes[i]->f) { + bzero(ulsch->harq_processes[i]->f,14*N_RB_UL*12*8); + } else { + printf("Can't get f\n"); + exit_flag=1; + } } ulsch->harq_processes[i]->subframe_scheduling_flag = 0; @@ -180,19 +206,17 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u } LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t)); - free_nr_ue_ulsch(ulsch); + free_nr_ue_ulsch(ulsch,N_RB_UL); return(NULL); } - int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, - NR_DL_FRAME_PARMS* frame_parms, - uint8_t harq_pid) + NR_DL_FRAME_PARMS* frame_parms, + uint8_t harq_pid) { - /////////////////////////parameters and variables declaration///////////////////////// /////////// @@ -205,11 +229,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, uint8_t mod_order; uint16_t Kr,r,r_offset; uint8_t BG; - uint32_t E; + uint32_t E,Kb; uint8_t Ilbrm; uint32_t Tbslbrm; uint8_t nb_re_dmrs; uint16_t length_dmrs; + uint16_t R; float Coderate; /////////// @@ -225,7 +250,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, nb_symb_sch = harq_process->number_of_symbols; A = harq_process->TBS; pz = &Z; - mod_order = nr_get_Qm(harq_process->mcs,1); + mod_order = nr_get_Qm_ul(harq_process->mcs,0); + R = nr_get_code_rate_ul(harq_process->mcs, 0); Kr=0; r_offset=0; BG = 1; @@ -239,13 +265,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, /////////// ///////////////////////////////////////////////////////////////////////////////////////// - /* - uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char - for(j=0;jNl); LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order); - - - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); // if (harq_process->Ndi == 1) { // this is a new packet if (harq_process->round == 0) { // this is a new packet @@ -290,16 +307,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, ///////////////////////// b---->| block segmentation |---->c ///////////////////////// /////////// - nr_segmentation(harq_process->b, - harq_process->c, - harq_process->B, - &harq_process->C, - &harq_process->K, - pz, - &harq_process->F); - - F = harq_process->F; - Coderate = (float) A /(float) G; + if (R<1024) + Coderate = (float) R /(float) 1024; + else + Coderate = (float) R /(float) 2048; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ BG = 2; @@ -308,6 +319,16 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, BG = 1; } + Kb=nr_segmentation(harq_process->b, + harq_process->c, + harq_process->B, + &harq_process->C, + &harq_process->K, + pz, + &harq_process->F, + BG); + + F = harq_process->F; Kr = harq_process->K; #ifdef DEBUG_DLSCH_CODING uint16_t Kr_bytes; @@ -317,6 +338,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, /////////// ///////////////////////////////////////////////////////////////////////////////////// +opp_enabled=0; ///////////////////////// c---->| LDCP coding |---->d ///////////////////////// /////////// @@ -351,7 +373,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, } printf("\n");*/ - ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); + ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); //stop_meas(te_stats); //printf("end ldpc encoder -- output\n"); @@ -376,7 +398,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, } #ifdef DEBUG_DLSCH_CODING - printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", + printf("Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d)...\n", r, G, Kr*3, @@ -393,6 +415,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r); + Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->Nl,harq_process->C); + nr_rate_matching_ldpc(Ilbrm, Tbslbrm, BG, @@ -400,6 +424,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, harq_process->d[r], harq_process->e+r_offset, harq_process->C, + F, + Kr-F-2*(*pz), harq_process->rvidx, E); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 2b59f93160..d2dbd6fef2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -43,77 +43,10 @@ #include "PHY/TOOLS/tools_defs.h" //#define DEBUG_SCFDMA - - -int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE, - uint8_t thread_id, - int gNB_id, - unsigned char harq_pid){ - - int N_PRB_oh, N_RE_prime, cwd_idx, length_dmrs, Nid_cell; - int nb_rb, Nsymb_pusch, first_rb, nb_codewords,mcs,rvidx; - uint16_t n_rnti; - - NR_UE_ULSCH_t *ulsch_ue; - NR_UL_UE_HARQ_t *harq_process_ul_ue; - - LOG_W(PHY,"This function should not be used. Use FAPI interfaces instead\n"); - - //--------------------------Temporary configuration-----------------------------// - length_dmrs = 1; - n_rnti = 0x1234; - Nid_cell = 0; - nb_rb = 50; - first_rb = 30; - Nsymb_pusch = 12; - nb_codewords = 1; - mcs = 9; - rvidx = 0; - //------------------------------------------------------------------------------// - - for (cwd_idx = 0; cwd_idx < nb_codewords; cwd_idx++) { - - ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_idx]; - harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid]; - - ulsch_ue->length_dmrs = length_dmrs; - ulsch_ue->rnti = n_rnti; - ulsch_ue->Nid_cell = Nid_cell; - ulsch_ue->Nsc_pusch = nb_rb*NR_NB_SC_PER_RB; - ulsch_ue->Nsymb_pusch = Nsymb_pusch; - ulsch_ue->nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4; - - - N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig - N_RE_prime = NR_NB_SC_PER_RB*Nsymb_pusch - ulsch_ue->nb_re_dmrs - N_PRB_oh; - - if (harq_process_ul_ue) { - - harq_process_ul_ue->mcs = mcs; - harq_process_ul_ue->Nl = nb_codewords; - harq_process_ul_ue->nb_rb = nb_rb; - harq_process_ul_ue->first_rb = first_rb; - harq_process_ul_ue->number_of_symbols = Nsymb_pusch; - harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords; - harq_process_ul_ue->rvidx = rvidx; - harq_process_ul_ue->TBS = nr_compute_tbs(harq_process_ul_ue->mcs, - nb_rb, - Nsymb_pusch, - ulsch_ue->nb_re_dmrs, - length_dmrs, - harq_process_ul_ue->Nl); - - } - - } - - return 0; -} - - +//#define DEBUG_PUSCH_MAPPING void nr_pusch_codeword_scrambling(uint8_t *in, - uint16_t size, + uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out) { @@ -151,39 +84,78 @@ void nr_pusch_codeword_scrambling(uint8_t *in, } -uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, +void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, unsigned char harq_pid, uint8_t slot, uint8_t thread_id, - int eNB_id) { + int gNB_id) { - unsigned int available_bits; + uint32_t available_bits; uint8_t mod_order, cwd_index, num_of_codewords; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; - int32_t *mod_symbols[MAX_NUM_NR_RE]; uint32_t ***pusch_dmrs; int16_t **tx_layers; int32_t **txdataF; uint16_t start_sc, start_rb; int8_t Wf[2], Wt[2], l0, l_prime[2], delta; - uint16_t n_dmrs; - uint8_t dmrs_type; + uint16_t n_dmrs,code_rate; + uint8_t dmrs_type, length_dmrs; uint8_t mapping_type; - int ap, start_symbol, i; - int sample_offsetF; + int ap, start_symbol, Nid_cell, i; + int sample_offsetF, N_RE_prime, N_PRB_oh; + uint16_t n_rnti; NR_UE_ULSCH_t *ulsch_ue; NR_UL_UE_HARQ_t *harq_process_ul_ue; NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; - NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][eNB_id]; + NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; num_of_codewords = 1; // tmp assumption + length_dmrs = 1; + n_rnti = 0x1234; + Nid_cell = 0; + N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) { - ulsch_ue = UE->ulsch[thread_id][eNB_id][cwd_index]; + ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index]; harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid]; + ulsch_ue->length_dmrs = length_dmrs; + ulsch_ue->rnti = n_rnti; + ulsch_ue->Nid_cell = Nid_cell; + ulsch_ue->nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1?6:4); + + N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs - N_PRB_oh; + + harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*harq_process_ul_ue->nb_rb*num_of_codewords; + + mod_order = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0); + code_rate = nr_get_code_rate_ul(harq_process_ul_ue->mcs, 0); + + harq_process_ul_ue->TBS = nr_compute_tbs(mod_order, + code_rate, + harq_process_ul_ue->nb_rb, + harq_process_ul_ue->number_of_symbols, + ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs, + 0, + harq_process_ul_ue->Nl); + + //-----------------------------------------------------// + // to be removed later when MAC is ready + + if (harq_process_ul_ue != NULL){ + for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { + harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf("input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + } + } else { + LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n"); + return; + } + + //-----------------------------------------------------// + /////////////////////////ULSCH coding///////////////////////// /////////// @@ -195,10 +167,10 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////ULSCH scrambling///////////////////////// /////////// - mod_order = nr_get_Qm(harq_process_ul_ue->mcs, 1); + mod_order = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0); available_bits = nr_get_G(harq_process_ul_ue->nb_rb, - ulsch_ue->Nsymb_pusch, + harq_process_ul_ue->number_of_symbols, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, mod_order, @@ -224,22 +196,19 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, mod_order, (int16_t *)ulsch_ue->d_mod); + // pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid); /////////// //////////////////////////////////////////////////////////////////////// - mod_symbols[cwd_index] = (int32_t *)malloc16((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t*)); - - memcpy(mod_symbols[cwd_index],ulsch_ue->d_mod,(available_bits/mod_order)*sizeof(int32_t)); } - start_symbol = 14 - ulsch_ue->Nsymb_pusch; + start_symbol = 14 - harq_process_ul_ue->number_of_symbols; /////////////////////////DMRS Modulation///////////////////////// /////////// - pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs); int16_t mod_dmrs[n_dmrs<<1]; @@ -249,7 +218,6 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, l0 = get_l0_ul(mapping_type, 2); nr_modulation(pusch_dmrs[l0][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated - /////////// //////////////////////////////////////////////////////////////////////// @@ -258,13 +226,10 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, tx_layers = (int16_t **)pusch_ue->txdataF_layers; - nr_layer_mapping((int16_t **)mod_symbols, + nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id], harq_process_ul_ue->Nl, available_bits/mod_order, tx_layers); - - for (uint32_t i = 0; i < 2*available_bits/mod_order; i++) - tx_layers[0][i] = (tx_layers[0][i] * AMP) >> 15; /////////// //////////////////////////////////////////////////////////////////////// @@ -280,7 +245,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint32_t nb_re_pusch, nb_re_dmrs_per_rb; uint32_t y_offset = 0; - for (l = start_symbol; l < start_symbol + ulsch_ue->Nsymb_pusch; l++) { + for (l = start_symbol; l < start_symbol + harq_process_ul_ue->number_of_symbols; l++) { if(l == dmrs_symbol) nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs; // [hna] ulsch_ue->nb_re_dmrs = 6 in this configuration @@ -324,7 +289,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t k_prime=0; uint16_t m=0, n=0, dmrs_idx=0, k=0; - for (l=start_symbol; lNsymb_pusch; l++) { + for (l=start_symbol; lnumber_of_symbols; l++) { k = start_sc; @@ -338,11 +303,12 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_PUSCH_MAPPING - printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", + printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1], ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); #endif + dmrs_idx++; k_prime++; k_prime&=1; @@ -372,23 +338,37 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// //////////////////////////////////////////////////////////////////////// - return 0; + return; } uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, + uint8_t harq_pid, uint8_t slot, - uint8_t Nl, + uint8_t thread_id, + uint8_t gNB_id, NR_DL_FRAME_PARMS *frame_parms) { int tx_offset, ap; int32_t **txdata; int32_t **txdataF; + int timing_advance; + uint8_t Nl = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->Nl; // cw 0 /////////////////////////IFFT/////////////////////// /////////// - tx_offset = slot*frame_parms->samples_per_slot; +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) + timing_advance = UE->timing_advance; +#else + timing_advance = 0; +#endif + + tx_offset = slot*frame_parms->samples_per_slot - timing_advance; + + if (tx_offset < 0) + tx_offset += frame_parms->samples_per_frame; + txdata = UE->common_vars.txdata; txdataF = UE->common_vars.txdataF; @@ -407,7 +387,6 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, frame_parms); } } - /////////// //////////////////////////////////////////////////// return 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c index 334faafecd..4012322111 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pbch_nr.c @@ -59,7 +59,7 @@ uint32_t *pseudo_random_gold_sequence(length M_PN, uint32_t cinit) { int size = M_PN * sizeof(uint32_t); - int size_x = (sizeof(int)*M_PN + size; + int size_x = sizeof(int)*M_PN + size; int *x1 = malloc(size_x); int *x2 = malloc(size_x); diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index c9fb300706..b13cd008b5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -234,8 +234,8 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) if (N_ID_2 == 0) { char output_file[255]; char sequence_name[255]; - sprintf(output_file, "pss_seq_%d_%d.m", N_ID_2, length); - sprintf(sequence_name, "pss_seq_%d_%d", N_ID_2, length); + sprintf(output_file, "pss_seq_%d_%u.m", N_ID_2, length); + sprintf(sequence_name, "pss_seq_%d_%u", N_ID_2, length); printf("file %s sequence %s\n", output_file, sequence_name); LOG_M(output_file, sequence_name, primary_synchro, LENGTH_PSS_NR, 1, 1); @@ -298,14 +298,14 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) if (N_ID_2 == 0) { char output_file[255]; char sequence_name[255]; - sprintf(output_file, "%s%d_%d%s","pss_seq_t_", N_ID_2, length, ".m"); - sprintf(sequence_name, "%s%d_%d","pss_seq_t_", N_ID_2, length); + sprintf(output_file, "%s%d_%u%s","pss_seq_t_", N_ID_2, length, ".m"); + sprintf(sequence_name, "%s%d_%u","pss_seq_t_", N_ID_2, length); printf("file %s sequence %s\n", output_file, sequence_name); LOG_M(output_file, sequence_name, primary_synchro_time, length, 1, 1); - sprintf(output_file, "%s%d_%d%s","pss_seq_f_", N_ID_2, length, ".m"); - sprintf(sequence_name, "%s%d_%d","pss_seq_f_", N_ID_2, length); + sprintf(output_file, "%s%d_%u%s","pss_seq_f_", N_ID_2, length, ".m"); + sprintf(sequence_name, "%s%d_%u","pss_seq_f_", N_ID_2, length); LOG_M(output_file, sequence_name, synchroF_tmp, length, 1, 1); } @@ -900,7 +900,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain pss_source = pss_index; #ifdef DEBUG_PSS_NR - printf("pss_index %d: n %6d peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[pss_index][n]); + printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[pss_index][n]); #endif } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 3d36822956..44d500b0b7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -341,7 +341,7 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, pss_rxF_ext = &pss_ext[aarx][0]; sss_rxF_ext = &sss_ext[aarx][0]; - unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; + unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size; for (int i=0; i < LENGTH_PSS_NR; i++) { diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index ccd09b34be..2de8653ab3 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -4836,22 +4836,22 @@ void idft4096(int16_t *x,int16_t *y,int scale) if (scale>0) { for (i=0; i<64; i++) { - y128[0] = shiftright_int16(y128[0],1); - y128[1] = shiftright_int16(y128[1],1); - y128[2] = shiftright_int16(y128[2],1); - y128[3] = shiftright_int16(y128[3],1); - y128[4] = shiftright_int16(y128[4],1); - y128[5] = shiftright_int16(y128[5],1); - y128[6] = shiftright_int16(y128[6],1); - y128[7] = shiftright_int16(y128[7],1); - y128[8] = shiftright_int16(y128[8],1); - y128[9] = shiftright_int16(y128[9],1); - y128[10] = shiftright_int16(y128[10],1); - y128[11] = shiftright_int16(y128[11],1); - y128[12] = shiftright_int16(y128[12],1); - y128[13] = shiftright_int16(y128[13],1); - y128[14] = shiftright_int16(y128[14],1); - y128[15] = shiftright_int16(y128[15],1); + y128[0] = shiftright_int16(y128[0],scale); + y128[1] = shiftright_int16(y128[1],scale); + y128[2] = shiftright_int16(y128[2],scale); + y128[3] = shiftright_int16(y128[3],scale); + y128[4] = shiftright_int16(y128[4],scale); + y128[5] = shiftright_int16(y128[5],scale); + y128[6] = shiftright_int16(y128[6],scale); + y128[7] = shiftright_int16(y128[7],scale); + y128[8] = shiftright_int16(y128[8],scale); + y128[9] = shiftright_int16(y128[9],scale); + y128[10] = shiftright_int16(y128[10],scale); + y128[11] = shiftright_int16(y128[11],scale); + y128[12] = shiftright_int16(y128[12],scale); + y128[13] = shiftright_int16(y128[13],scale); + y128[14] = shiftright_int16(y128[14],scale); + y128[15] = shiftright_int16(y128[15],scale); y128+=16; } @@ -8591,6 +8591,8 @@ void dft1200(int16_t *x,int16_t *y,unsigned char scale_flag) } +//#define round trunc + void init_rad4(int N,int16_t *tw) { int16_t *twa = tw; @@ -8760,6 +8762,8 @@ void init_dfts(void) init_rad4_rep(1200,twa1200,twb1200,twc1200); } +//#undef round + #ifdef MR_MAIN #include #include diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 3ac1676983..dbcd9540be 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -559,7 +559,10 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); - llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero + //llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. + llr = (float*) malloc(coded_bits_per_codeword*sizeof(float)); + memset((void *)llr, 0,coded_bits_per_codeword*sizeof(float)); // init to zero + bit = malloc(coded_bits_per_codeword*sizeof(float)); llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); @@ -572,7 +575,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr; pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0]; pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0 - // pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0 + //pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0 pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0]; pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0]; diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index 5c7322e2e9..d44f8e325b 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -31,6 +31,7 @@ float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; float tput_ue_max[NUMBER_OF_UE_MAX] = {0}; + static void ia_receiver_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { @@ -43,6 +44,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg) fl_set_object_color(button, FL_RED, FL_RED); } } + static void dl_traffic_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { @@ -140,6 +142,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fdui->lte_phy_scope_enb->fdui = fdui; return fdui; } + void phy_scope_eNB(FD_lte_phy_scope_enb *form, PHY_VARS_eNB *phy_vars_enb, int UE_id) @@ -325,7 +328,9 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, free(bit); free(chest_f_abs); } -FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { + +FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) +{ FL_OBJECT *obj; FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui ); // Define form @@ -429,11 +434,13 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { fdui->lte_phy_scope_ue->fdui = fdui; return fdui; } + void phy_scope_UE(FD_lte_phy_scope_ue *form, PHY_VARS_UE *phy_vars_ue, int eNB_id, int UE_id, - uint8_t subframe){ + uint8_t subframe) +{ int i,arx,atx,ind,k; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; @@ -492,14 +499,14 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) { mod0 = get_Qm(mcs0); coded_bits_per_codeword0 = get_G(frame_parms, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - get_Qm(mcs0), - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, - num_pdcch_symbols, - frame, - subframe, - beamforming_mode); + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs0), + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe, + beamforming_mode); } else { coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); mod0=0; @@ -507,14 +514,14 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) { mod1 = get_Qm(mcs1); coded_bits_per_codeword1 = get_G(frame_parms, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, - get_Qm(mcs1), - phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl, - num_pdcch_symbols, - frame, - subframe, - beamforming_mode); + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs1), + phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe, + beamforming_mode); } else { coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); mod1=0; @@ -526,9 +533,14 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, chest_t_abs[arx] = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float)); } chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); - llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // init to zero + //llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. + llr0 = (float*) malloc(coded_bits_per_codeword0*sizeof(float)); + memset((void *)llr0, 0,coded_bits_per_codeword0*sizeof(float)); // init to zero bit0 = malloc(coded_bits_per_codeword0*sizeof(float)); - llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // init to zero + + //llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. + llr1 = (float*) malloc(coded_bits_per_codeword1*sizeof(float)); + memset((void *)llr1, 0,coded_bits_per_codeword1*sizeof(float)); // init to zero bit1 = malloc(coded_bits_per_codeword1*sizeof(float)); llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); @@ -822,6 +834,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, for (int m=0; mpdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0; }*/ - } - - +} diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 8259f0d9c3..2c22706968 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -23,6 +23,7 @@ #include #include "nr_phy_scope.h" +#include "executables/nr-softmodem-common.h" #define TPUT_WINDOW_LENGTH 100 int otg_enabled; @@ -176,7 +177,7 @@ void phy_scope_gNB(FD_phy_scope_gnb *form, float time[FRAME_LENGTH_COMPLEX_SAMPLES]; float time2[2048]; float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx]; - uint32_t total_dlsch_bitrate = phy_vars_gnb->total_dlsch_bitrate; +// uint32_t total_dlsch_bitrate = phy_vars_gnb->total_dlsch_bitrate; int coded_bits_per_codeword = 0; uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2 int Qm = 2; @@ -363,7 +364,7 @@ void phy_scope_gNB(FD_phy_scope_gnb *form, memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) 0; - tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; +// tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; fl_set_xyplot_data(form->pusch_tput,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","",""); @@ -588,8 +589,8 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form, time = calloc(samples_per_frame,sizeof(float)); corr = calloc(samples_per_frame,sizeof(float)); - chest_t = (int16_t**) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time; - chest_f = (int16_t**) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates; + chest_t = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time; + chest_f = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates; pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; @@ -696,8 +697,8 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form, if (chest_f[(atx<<1)+arx] != NULL) { for (k=0; kofdm_symbol_size; k++) { freq[ind] = (float)ind; - Re = (float)(chest_f[(atx<<1)+arx][(2*k)]); - Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]); + Re = (float)(chest_f[(atx<<1)+arx][6144+(2*k)]); + Im = (float)(chest_f[(atx<<1)+arx][6144+(2*k)+1]); chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im)); ind++; diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h index 37331b511d..770006d234 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.h +++ b/openair1/PHY/TOOLS/nr_phy_scope.h @@ -29,7 +29,6 @@ #include #include "common/ran_context.h" #include -#include #include #include "PHY/defs_gNB.h" //#include "PHY/defs_nrUE.h" @@ -67,6 +66,11 @@ typedef struct { FL_OBJECT * button_0; } FD_phy_scope_nrue; +typedef struct { + int *argc; + char **argv; +} scopeParms_t; + extern unsigned char scope_enb_num_ue; FD_phy_scope_gnb * create_phy_scope_gnb( void ); FD_phy_scope_nrue * create_phy_scope_nrue( void ); @@ -82,5 +86,10 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form, int eNB_id, int UE_id, uint8_t subframe); + + +void startScope(scopeParms_t * p); + + extern RAN_CONTEXT_t RC; #endif diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index e5233efb63..4253eb28d3 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -32,8 +32,6 @@ #include #include "PHY/sse_intrin.h" -#define CEILIDIV(a,b) ((a+b-1)/b) -#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) struct complex { double x; diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 80d63cbdd9..fa4aef2c76 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -104,6 +104,10 @@ typedef struct { /// - first index: tx antenna [0..nb_antennas_tx[ /// - second index: sample [0..] int32_t **txdataF_BF; + /// \brief holds the transmit data before beamforming in the frequency domain. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..] + int32_t **txdataF; /// \brief holds the transmit data before beamforming for epdcch/mpdcch /// - first index : tx antenna [0..nb_epdcch_antenna_ports[ /// - second index: sampl [0..] @@ -147,6 +151,44 @@ typedef struct { } RU_CALIBRATION; +typedef struct RU_prec_t_s{ + /// \internal This variable is protected by \ref mutex_feptx_prec + int instance_cnt_feptx_prec; + /// pthread struct for RU TX FEP PREC worker thread + pthread_t pthread_feptx_prec; + /// pthread attributes for worker feptx prec thread + pthread_attr_t attr_feptx_prec; + /// condition varible for RU TX FEP PREC thread + pthread_cond_t cond_feptx_prec; + /// mutex for fep PREC TX worker thread + pthread_mutex_t mutex_feptx_prec; + int symbol; + int p;//logical + int aa;//physical MAX nb_tx + struct RU_t_s *ru; + int index; +} RU_prec_t; + +typedef struct RU_feptx_t_s{ + /// \internal This variable is protected by \ref mutex_feptx_prec + int instance_cnt_feptx; + /// pthread struct for RU TX FEP PREC worker thread + pthread_t pthread_feptx; + /// pthread attributes for worker feptx prec thread + pthread_attr_t attr_feptx; + /// condition varible for RU TX FEP PREC thread + pthread_cond_t cond_feptx; + /// mutex for fep PREC TX worker thread + pthread_mutex_t mutex_feptx; + struct RU_t_s *ru; + int aa;//physical MAX nb_tx + int half_slot;//first or second half of a slot + int slot;//current slot + int symbol;//current symbol + int nb_antenna_ports;//number of logical port + int index; +}RU_feptx_t; + typedef struct RU_proc_t_s { /// Pointer to associated RU descriptor struct RU_t_s *ru; @@ -339,8 +381,14 @@ typedef struct RU_proc_t_s { int ru_rx_ready; int ru_tx_ready; int emulate_rf_busy; -} RU_proc_t; + /// structure for precoding thread + RU_prec_t prec[16]; + /// structure for feptx thread + RU_feptx_t feptx[16]; + /// mask for checking process finished + int feptx_mask; +} RU_proc_t; typedef enum { LOCAL_RF =0, @@ -420,6 +468,8 @@ typedef struct RU_t_s { int nb_rx; /// number of TX paths on device int nb_tx; + /// number of logical antennas at TX beamformer input + int nb_log_antennas; /// maximum PDSCH RS EPRE int max_pdschReferenceSignalPower; /// maximum RX gain @@ -495,10 +545,16 @@ typedef struct RU_t_s { void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru); void (*gNB_top)(struct PHY_VARS_gNB_s *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru); + /// Timing data copy statistics (TX) + time_stats_t txdataF_copy_stats; + /// Timing statistics (TX) + time_stats_t precoding_stats; /// Timing statistics time_stats_t ofdm_demod_stats; /// Timing statistics (TX) time_stats_t ofdm_mod_stats; + /// Timing statistics (TX) + time_stats_t ofdm_total_stats; /// Timing wait statistics time_stats_t ofdm_demod_wait_stats; /// Timing wakeup statistics @@ -518,10 +574,12 @@ typedef struct RU_t_s { /// RX and TX buffers for precoder output RU_COMMON common; RU_CALIBRATION calibration; - /// beamforming weight vectors per eNB + /// beamforming weight list size + int nb_bfw; + /// beamforming weight list of values + int32_t *bw_list[NUMBER_OF_eNB_MAX+1]; + /// beamforming weight vectors int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; - /// beamforming weight vectors per gNB - int32_t **nrbeam_weights[NUMBER_OF_gNB_MAX+1][16]; /// received frequency-domain signal for PRACH (IF4p5 RRU) int16_t **prach_rxsigF; /// received frequency-domain signal for PRACH BR (IF4p5 RRU) diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index ce8533a6e8..e5cbe4b756 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -88,6 +88,7 @@ #define LTE_CE_OFFSET LTE_CE_FILTER_LENGTH #define TX_RX_SWITCH_SYMBOL (NUMBER_OF_SYMBOLS_PER_FRAME>>1) #define PBCH_PDU_SIZE 3 //bytes +#define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14 #define PRACH_SYMBOL 3 //position of the UL PSS wrt 2nd slot of special subframe @@ -902,39 +903,6 @@ typedef struct THREAD_STRUCT_s { PARALLEL_CONF_t parallel_conf; WORKER_CONF_t worker_conf; } THREAD_STRUCT; -/*extern THREAD_STRUCT thread_struct; - -static inline void set_parallel_conf(char *parallel_conf) { - mapping config[]= { - FOREACH_PARALLEL(GENERATE_ENUMTXT) - {NULL,-1} - }; - thread_struct.parallel_conf = (PARALLEL_CONF_t)map_str_to_int(config, parallel_conf); - if (thread_struct.parallel_conf == -1 ) { - LOG_E(ENB_APP,"Impossible value: %s\n", parallel_conf); - thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - } -} - -static inline void set_worker_conf(char *worker_conf) { - mapping config[]={ - FOREACH_WORKER(GENERATE_ENUMTXT) - {NULL, -1} - }; - thread_struct.worker_conf = (WORKER_CONF_t)map_str_to_int(config, worker_conf); - if (thread_struct.worker_conf == -1 ) { - LOG_E(ENB_APP,"Impossible value: %s\n", worker_conf); - thread_struct.worker_conf = WORKER_DISABLE ; - } -} - -static inline PARALLEL_CONF_t get_thread_parallel_conf(void) { - return thread_struct.parallel_conf; -} - -static inline WORKER_CONF_t get_thread_worker_conf(void) { - return thread_struct.worker_conf; -}*/ typedef enum {SF_DL, SF_UL, SF_S} lte_subframe_t; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index cae03f2763..52aade312a 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -61,29 +61,6 @@ typedef struct { } NR_PBCH_parms_t; -typedef struct { - /// Length of DCI payload in bits - uint16_t size; - /// Aggregation level - uint8_t L; - /// HARQ PID - uint8_t harq_pid; - /// PDCCH parameters - nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params; - /// CCE list - nr_cce_t cce_list[NR_MAX_PDCCH_AGG_LEVEL]; - /// DCI pdu - uint64_t dci_pdu[2]; -} NR_gNB_DCI_ALLOC_t; - - -typedef struct { - uint8_t num_dci; - uint8_t num_pdsch_rnti; - NR_gNB_DCI_ALLOC_t dci_alloc[256]; -} NR_gNB_PDCCH; - - typedef enum { NR_SCH_IDLE, NR_ACTIVE, @@ -94,7 +71,7 @@ typedef enum { typedef struct { /// Nfapi DLSCH PDU - nfapi_nr_dl_config_dlsch_pdu dlsch_pdu; + nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu; /// pointer to pdu from MAC interface (this is "a" in 36.212) uint8_t *pdu; /// The payload + CRC size in bits, "B" from 36-212 @@ -112,11 +89,11 @@ typedef struct { /// MIMO mode for this DLSCH MIMO_mode_t mimo_mode; /// Concatenated sequences - uint8_t e[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); + uint8_t *e; /// LDPC-code outputs uint8_t *d[MAX_NUM_NR_DLSCH_SEGMENTS]; /// Interleaver outputs - uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); + uint8_t *f; /// Number of code segments uint32_t C; /// Number of bits in "small" code segments @@ -296,7 +273,7 @@ typedef struct { /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled uint8_t h[MAX_NUM_CHANNEL_BITS]; /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) - int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; + int16_t *w[MAX_NUM_NR_ULSCH_SEGMENTS]; ////////////////////////////////////////////////////////////// } NR_UL_gNB_HARQ_t; @@ -377,11 +354,15 @@ typedef struct { /// \brief Hold the channel estimates in time domain based on DRS. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..4*ofdm_symbol_size[ - int32_t **drs_ch_estimates_time; + int32_t **ul_ch_estimates_time; /// \brief Hold the channel estimates in frequency domain based on DRS. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ - int32_t **drs_ch_estimates; + int32_t **ul_ch_estimates; + /// \brief Uplink channel estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_estimates_ext; /// \brief Holds the compensated signal. /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ @@ -394,6 +375,28 @@ typedef struct { /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ int32_t **ul_ch_magb; + /// \brief Cross-correlation of two UE signals. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..] + int32_t **rho; + /// \f$\log_2(\max|H_i|^2)\f$ + int16_t log2_maxh; + /// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_UL[ + int32_t **ul_ch_mag0; + /// \brief Magnitude of Uplink Channel second layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_UL[ + int32_t **ul_ch_mag1[8][8]; + /// \brief Magnitude of Uplink Channel, first layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_UL[ + int32_t **ul_ch_magb0; + /// \brief Magnitude of Uplink Channel second layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_UL[ + int32_t **ul_ch_magb1[8][8]; /// measured RX power based on DRS int ulsch_power[2]; /// \brief llr values. @@ -595,12 +598,13 @@ typedef struct PHY_VARS_gNB_s { int rx_total_gain_dB; int (*nr_start_if)(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB); uint8_t local_flag; - nfapi_nr_config_request_t gNB_config; + nfapi_nr_config_request_scf_t gNB_config; NR_DL_FRAME_PARMS frame_parms; PHY_MEASUREMENTS_gNB measurements; NR_IF_Module_t *if_inst; NR_UL_IND_t UL_INFO; pthread_mutex_t UL_INFO_mutex; + /// NFAPI RX ULSCH information nfapi_rx_indication_pdu_t rx_pdu_list[NFAPI_RX_IND_MAX_PDU]; /// NFAPI RX ULSCH CRC information @@ -616,27 +620,24 @@ typedef struct PHY_VARS_gNB_s { /// NFAPI PRACH information nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; - Sched_Rsp_t Sched_INFO; - NR_gNB_PDCCH pdcch_vars; - NR_gNB_PBCH pbch; - // LTE_eNB_PHICH phich_vars[2]; + //Sched_Rsp_t Sched_INFO; + nfapi_nr_ul_tti_request_t UL_tti_req; + + nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu; + nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu; + nfapi_nr_dl_tti_ssb_pdu ssb_pdu; - NR_gNB_COMMON common_vars; -/* LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; - LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];*/ + int num_pdsch_rnti; + NR_gNB_PBCH pbch; + nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]; + NR_gNB_COMMON common_vars; NR_gNB_PRACH prach_vars; - NR_gNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; + NR_gNB_PUSCH *pusch_vars[NUMBER_OF_NR_ULSCH_MAX]; NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams - NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA - // LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA + NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords] NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p; NR_gNB_DLSCH_t *dlsch_PCH; -/* - LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX]; - LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX]; -*/ uint8_t pbch_configured; - uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE char gNB_generate_rar; /// NR synchronization sequences @@ -654,9 +655,12 @@ typedef struct PHY_VARS_gNB_s { /// PDSCH DMRS sequence uint32_t ****nr_gold_pdsch_dmrs; + + /// PUSCH DMRS + uint32_t nr_gold_pusch[2][20][2][NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD]; /// Indicator set to 0 after first SR - uint8_t first_sr[NUMBER_OF_UE_MAX]; + uint8_t first_sr[NUMBER_OF_NR_SR_MAX]; /// PRACH root sequence uint32_t X_u[64][839]; @@ -670,7 +674,6 @@ typedef struct PHY_VARS_gNB_s { /// N0 (used for abstraction) double N0; - unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX]; unsigned char first_run_I0_measurements; @@ -688,89 +691,29 @@ typedef struct PHY_VARS_gNB_s { /// counter to average prach energh over first 100 prach opportunities int prach_energy_counter; - // PDSCH Variables - PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_UE_MAX]; - - // PUSCH Varaibles - PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_UE_MAX]; - - // PUCCH variables - PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_UE_MAX]; - - // UL-POWER-Control - UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_UE_MAX]; - - // TPC - TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX]; - TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX]; - - // CQI reporting - CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_UE_MAX]; - - // SRS Variables - SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX]; - uint8_t ncs_cell[20][7]; - - // Scheduling Request Config - SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_UE_MAX]; - - // Transmission mode per UE - uint8_t transmission_mode[NUMBER_OF_UE_MAX]; - - /// cba_last successful reception for each group, used for collision detection - uint8_t cba_last_reception[4]; - - // Pointers for active physicalConfigDedicated to be applied in current slot - struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX]; - - - uint32_t rb_mask_ul[4]; - - /// Information regarding TM5 - MU_MIMO_mode mu_mimo_mode[NUMBER_OF_UE_MAX]; - - - /// target_ue_dl_mcs : only for debug purposes - uint32_t target_ue_dl_mcs; - /// target_ue_ul_mcs : only for debug purposes - uint32_t target_ue_ul_mcs; - /// target_ue_dl_rballoc : only for debug purposes - uint32_t ue_dl_rb_alloc; - /// target ul PRBs : only for debug - uint32_t ue_ul_nb_rb; - - ///check for Total Transmissions - uint32_t check_for_total_transmissions; - - ///check for MU-MIMO Transmissions - uint32_t check_for_MUMIMO_transmissions; - - ///check for SU-MIMO Transmissions - uint32_t check_for_SUMIMO_transmissions; - - ///check for FULL MU-MIMO Transmissions - uint32_t FULL_MUMIMO_transmissions; - - /// Counter for total bitrate, bits and throughput in downlink - uint32_t total_dlsch_bitrate; - uint32_t total_transmitted_bits; - uint32_t total_system_throughput; - - int hw_timing_advance; - + /* time_stats_t phy_proc; + */ time_stats_t phy_proc_tx; + /* time_stats_t phy_proc_rx; + */ time_stats_t rx_prach; - + /* time_stats_t ofdm_mod_stats; + */ time_stats_t dlsch_encoding_stats; time_stats_t dlsch_modulation_stats; time_stats_t dlsch_scrambling_stats; + time_stats_t tinput; + time_stats_t tprep; + time_stats_t tparity; + time_stats_t toutput; + time_stats_t dlsch_rate_matching_stats; - time_stats_t dlsch_turbo_encoding_stats; time_stats_t dlsch_interleaving_stats; - + time_stats_t dlsch_segmentation_stats; + /* time_stats_t rx_dft_stats; time_stats_t ulsch_channel_estimation_stats; time_stats_t ulsch_freq_offset_estimation_stats; @@ -781,29 +724,7 @@ typedef struct PHY_VARS_gNB_s { time_stats_t ulsch_deinterleaving_stats; time_stats_t ulsch_demultiplexing_stats; time_stats_t ulsch_llr_stats; - time_stats_t ulsch_tc_init_stats; - time_stats_t ulsch_tc_alpha_stats; - time_stats_t ulsch_tc_beta_stats; - time_stats_t ulsch_tc_gamma_stats; - time_stats_t ulsch_tc_ext_stats; - time_stats_t ulsch_tc_intl1_stats; - time_stats_t ulsch_tc_intl2_stats; - -#ifdef LOCALIZATION - /// time state for localization - time_stats_t localization_stats; -#endif - - int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX][10]; - int32_t pucch1_stats[NUMBER_OF_UE_MAX][10*1024]; - int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX][10*1024]; - int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX][10]; - int32_t pucch1ab_stats[NUMBER_OF_UE_MAX][2*10*1024]; - int32_t pusch_stats_rb[NUMBER_OF_UE_MAX][10240]; - int32_t pusch_stats_round[NUMBER_OF_UE_MAX][10240]; - int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240]; - int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240]; - int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240]; + */ } PHY_VARS_gNB; #endif diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index b4b9ff00c0..a1f9ca9bdc 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -45,6 +45,7 @@ #include #include "common_lib.h" #include "msc.h" +#include "fapi_nr_ue_interface.h" //#include #include "assertions.h" @@ -470,65 +471,7 @@ typedef struct { #ifdef NR_PDCCH_DEFS_NR_UE #define MAX_NR_DCI_DECODED_SLOT 10 // This value is not specified -#define NBR_NR_FORMATS 8 // The number of formats is 8 (0_0, 0_1, 1_0, 1_1, 2_0, 2_1, 2_2, 2_3) -#define NBR_NR_DCI_FIELDS 56 // The number of different dci fields defined in TS 38.212 subclause 7.3.1 -#define IDENTIFIER_DCI_FORMATS 0 -#define CARRIER_IND 1 -#define SUL_IND_0_1 2 -#define SLOT_FORMAT_IND 3 -#define PRE_EMPTION_IND 4 -#define BLOCK_NUMBER 5 -#define CLOSE_LOOP_IND 6 -#define BANDWIDTH_PART_IND 7 -#define SHORT_MESSAGE_IND 8 -#define SHORT_MESSAGES 9 -#define FREQ_DOM_RESOURCE_ASSIGNMENT_UL 10 -#define FREQ_DOM_RESOURCE_ASSIGNMENT_DL 11 -#define TIME_DOM_RESOURCE_ASSIGNMENT 12 -#define VRB_TO_PRB_MAPPING 13 -#define PRB_BUNDLING_SIZE_IND 14 -#define RATE_MATCHING_IND 15 -#define ZP_CSI_RS_TRIGGER 16 -#define FREQ_HOPPING_FLAG 17 -#define TB1_MCS 18 -#define TB1_NDI 19 -#define TB1_RV 20 -#define TB2_MCS 21 -#define TB2_NDI 22 -#define TB2_RV 23 -#define MCS 24 -#define NDI 25 -#define RV 26 -#define HARQ_PROCESS_NUMBER 27 -#define DAI_ 28 -#define FIRST_DAI 29 -#define SECOND_DAI 30 -#define TB_SCALING 31 -#define TPC_PUSCH 32 -#define TPC_PUCCH 33 -#define PUCCH_RESOURCE_IND 34 -#define PDSCH_TO_HARQ_FEEDBACK_TIME_IND 35 -#define SRS_RESOURCE_IND 36 -#define PRECOD_NBR_LAYERS 37 -#define ANTENNA_PORTS 38 -#define TCI 39 -#define SRS_REQUEST 40 -#define TPC_CMD 41 -#define CSI_REQUEST 42 -#define CBGTI 43 -#define CBGFI 44 -#define PTRS_DMRS 45 -#define BETA_OFFSET_IND 46 -#define DMRS_SEQ_INI 47 -#define UL_SCH_IND 48 -#define PADDING_NR_DCI 49 -#define SUL_IND_0_0 50 -#define RA_PREAMBLE_INDEX 51 -#define SUL_IND_1_0 52 -#define SS_PBCH_INDEX 53 -#define PRACH_MASK_INDEX 54 -#define RESERVED_NR_DCI 55 typedef enum { @@ -759,12 +702,6 @@ typedef struct { /// \brief PDCCH/DCI e-sequence (input to rate matching). /// - first index: ? [0..96*N_RB_DL[ int16_t *e_rx; - /// number of PDCCH symbols in current subframe - uint8_t num_pdcch_symbols; - /// Allocated CRNTI for UE - uint16_t crnti; - /// 1: the allocated crnti is Temporary C-RNTI / 0: otherwise - uint8_t crnti_is_temporary; /// Total number of PDU errors (diagnostic mode) uint32_t dci_errors; /// Total number of PDU received @@ -773,11 +710,14 @@ typedef struct { uint32_t dci_false; /// Total number of DCI missed (diagnostic mode) uint32_t dci_missed; - /// nCCE for PUCCH per subframe + /// nCCE for PDCCH per subframe uint8_t nCCE[10]; //Check for specific DCIFormat and AgregationLevel uint8_t dciFormat; uint8_t agregationLevel; + int nb_search_space; + fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS_PER_CORESET]; + /* #ifdef NR_PDCCH_DEFS_NR_UE int nb_searchSpaces; // CORESET structure, where maximum number of CORESETs to be handled is 3 (according to 38.331 V15.1.0) @@ -788,7 +728,7 @@ typedef struct { int n_RB_BWP[NR_NBR_SEARCHSPACE_ACT_BWP]; uint32_t nb_search_space; -#endif + #endif*/ } NR_UE_PDCCH; #define PBCH_A 24 @@ -810,6 +750,10 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..287] (hard coded) int32_t **dl_ch_estimates_ext; + /// \brief Hold the channel estimates in time domain (used for tracking). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: samples? [0..2*ofdm_symbol_size[ + int32_t **dl_ch_estimates_time; int log2_maxh; uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3]; uint32_t pbch_a_interleaved; @@ -945,6 +889,7 @@ typedef struct { // point to the current rxTx thread index uint8_t current_thread_id[40]; + t_nrPolar_params *polarList; NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads NR_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1]; NR_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1]; @@ -990,7 +935,7 @@ typedef struct { uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; /// PDSCH DMRS - uint32_t nr_gold_pdsch[2][20][2][52]; + uint32_t nr_gold_pdsch[2][20][2][NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD]; /// PDCCH DMRS uint32_t nr_gold_pdcch[7][20][3][52]; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 1cc8ccd69f..7b931a5ce4 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -35,7 +35,7 @@ #include "PHY/impl_defs_top.h" #include "defs_common.h" -#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "impl_defs_nr.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" @@ -102,13 +102,13 @@ #define NR_MAX_PUSCH_ENCODED_LENGTH NR_MAX_PDSCH_ENCODED_LENGTH #define NR_MAX_PDSCH_TBS 3824 -#define MAX_NUM_NR_DLSCH_SEGMENTS 16 +#define MAX_NUM_NR_DLSCH_SEGMENTS 34 #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) #define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056) -#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB +#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8) // 14 symbols, 273 RB #define MAX_NUM_NR_RE (14*273*12) typedef enum { @@ -226,10 +226,10 @@ typedef struct { typedef struct NR_DL_FRAME_PARMS { /// frequency range nr_frequency_range_e freq_range; - /// Placeholder to replace overlapping fields below - nfapi_nr_rf_config_t rf_config; + // /// Placeholder to replace overlapping fields below + // nfapi_nr_rf_config_t rf_config; /// Placeholder to replace SSB overlapping fields below - nfapi_nr_sch_config_t sch_config; + // nfapi_nr_sch_config_t sch_config; /// Number of resource blocks (RB) in DL int N_RB_DL; /// Number of resource blocks (RB) in UL @@ -239,11 +239,11 @@ typedef struct NR_DL_FRAME_PARMS { /// Total Number of Resource Block Groups SubSets: this is P uint8_t N_RBGS; /// EUTRA Band - uint8_t eutra_band; + uint16_t eutra_band; /// DL carrier frequency - uint32_t dl_CarrierFreq; + uint64_t dl_CarrierFreq; /// UL carrier frequency - uint32_t ul_CarrierFreq; + uint64_t ul_CarrierFreq; /// TX attenuation uint32_t att_tx; /// RX attenuation @@ -321,6 +321,8 @@ typedef struct NR_DL_FRAME_PARMS { /// TDD configuration uint16_t tdd_uplink_nr[2*NR_MAX_SLOTS_PER_FRAME]; /* this is a bitmap of symbol of each slot given for 2 frames */ + uint8_t half_frame_bit; + //SSB related params /// Start in Subcarrier index of the SSB block uint16_t ssb_start_subcarrier; @@ -330,6 +332,8 @@ typedef struct NR_DL_FRAME_PARMS { uint8_t Lmax; /// SS block pattern (max 64 ssb, each bit is on/off ssb) uint64_t L_ssb; + /// Total number of SSB transmitted + uint8_t N_ssb; /// PBCH polar encoder params t_nrPolar_params pbch_polar_params; diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 7b648515f5..6a5cf76f98 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -97,6 +97,7 @@ SystemInformationBlockType1_nr_t; #define NR_DOWNLINK_SLOT (0x01) #define NR_UPLINK_SLOT (0x02) +#define NR_MIXED_SLOT (0x03) #define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */ diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 1f7eb2aa44..a4607d3106 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -208,6 +208,7 @@ /// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$) #define QAM16_n1 20724 + /// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$) #define QAM16_n2 10362 diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 12f7c856b4..c0afdf25d1 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1134,6 +1134,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe); + int rvidx_tab[4] = {0,2,3,1}; for (i = 0; i < NUMBER_OF_UE_MAX; i++) { ulsch = eNB->ulsch[i]; @@ -1150,8 +1151,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { if ((ulsch) && (ulsch->rnti>0) && (ulsch_harq->status == ACTIVE) && - (ulsch_harq->frame == frame) && - (ulsch_harq->subframe == subframe) && + ((ulsch_harq->frame == frame) || (ulsch_harq->repetition_number >1) ) && + ((ulsch_harq->subframe == subframe) || (ulsch_harq->repetition_number >1) ) && (ulsch_harq->handled == 0)) { // UE has ULSCH scheduling for (int rb=0; @@ -1208,6 +1209,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { ulsch_harq->cqi_crc_status, ulsch_harq->O_ACK, eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max); + if (ulsch_harq->repetition_number < ulsch_harq->total_number_of_repetitions){ + ulsch_harq->rvidx = rvidx_tab[(ulsch_harq->repetition_number%4)] ; // Set the correct rvidx for the next emtc repetitions + ulsch_harq->repetition_number +=1 ; // Increment repetition_number for the next ULSCH allocation + } //compute the expected ULSCH RX power (for the stats) ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered @@ -1263,7 +1268,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { */ ulsch_harq->handled = 1; } // ulsch in error - else { + else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){ fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC ulsch_harq->status = SCH_IDLE; diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h index 150b0c194f..e74b9a312f 100644 --- a/openair1/SCHED/sched_eNB.h +++ b/openair1/SCHED/sched_eNB.h @@ -218,6 +218,8 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); void release_rnti_of_phy(module_id_t mod_id); + +void ru_fep_full_2thread(RU_t *ru, int subframe); /*@}*/ diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index dfe3527f9e..e8f7b2bba4 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -30,54 +30,100 @@ * \warning */ #include "fapi_nr_l1.h" +#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req); -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); extern uint8_t nfapi_mode; -void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB, - nfapi_nr_dl_config_request_pdu_t *dl_config_pdu, - uint8_t *sdu) +void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu) { - AssertFatal(dl_config_pdu->bch_pdu_rel15.length == 3, "BCH PDU has length %d != 3\n", - dl_config_pdu->bch_pdu_rel15.length); + AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n", + dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag); - LOG_D(PHY,"pbch_pdu[0]: %x,pbch_pdu[1]: %x,gNB->pbch_pdu[2]: %x\n",sdu[0],sdu[1],sdu[2]); - gNB->pbch_pdu[0] = sdu[2]; - gNB->pbch_pdu[1] = sdu[1]; - gNB->pbch_pdu[2] = sdu[0]; - - // adjust transmit amplitude here based on NFAPI info + LOG_I(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload); + memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu)); } +/*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc, + uint8_t codeword_index, + uint8_t *sdu) +{ -void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB, - int frame, int slot, - nfapi_nr_dl_config_dci_dl_pdu *dci_dl_pdu) { - int idx = slot&1; - NR_gNB_PDCCH *pdcch_vars = &gNB->pdcch_vars; + int UE_id = 0; //Hardcode UE_id for now + int harq_pid; - LOG_D(PHY,"Frame %d, Slot %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,slot, pdcch_vars->num_dci, slot, idx, pdcch_vars->num_dci); + NR_gNB_DLSCH_t *dlsch0=NULL, *dlsch1=NULL; + NR_DL_gNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; + + // Based on nr_fill_dci_and_dlsch only gNB->dlsch[0][0] gets filled now. So maybe we do not need dlsch1. + dlsch0 = gNB->dlsch[UE_id][0]; + dlsch1 = gNB->dlsch[UE_id][1]; + + harq_pid = dlsch0->harq_ids[subframe]; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + + + //if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU + if(sdu == NULL) { + LOG_E(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0 \n", + frame,subframe, + proc->frame_tx,proc->slot_tx); + return; + } + //AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", + // frame,subframe, + // proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, + // dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start); + if (codeword_index == 0) dlsch0_harq->pdu = sdu; + else dlsch1_harq->pdu = sdu; + LOG_I(PHY, "SFN/SF: %d/%d DLSCH PDU filled \n",frame, subframe); +// } + +}*/ + + +void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu) { + + LOG_D(PHY,"Frame %d, Slot %d: DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, pdcch_pdu->pdcch_pdu_rel15.numDlDci); // copy dci configuration into gNB structure - nr_fill_dci(gNB,frame,slot,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],dci_dl_pdu); + gNB->pdcch_pdu = pdcch_pdu; + + nr_fill_dci(gNB,frame,slot); + - LOG_D(PHY,"Frame %d, Slot %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,slot, pdcch_vars->num_dci, slot, idx, pdcch_vars->num_dci); } +void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, + int frame, int slot, + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu) { -void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + LOG_D(PHY,"Frame %d, Slot %d: UL DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15.numDlDci); + + // copy dci configuration into gNB structure + gNB->ul_dci_pdu = ul_dci_request_pdu; + + nr_fill_ul_dci(gNB,frame,slot); + + + +} + +void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, uint8_t *sdu) { - nr_fill_dlsch(gNB,frame,slot,dlsch_pdu,sdu); + nr_fill_dlsch(gNB,frame,slot,pdsch_pdu,sdu); } @@ -87,9 +133,10 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ // copy data from L2 interface into L1 structures module_id_t Mod_id = Sched_INFO->module_id; uint8_t CC_id = Sched_INFO->CC_id; - nfapi_nr_dl_config_request_t *DL_req = Sched_INFO->DL_req; - nfapi_tx_request_t *TX_req = Sched_INFO->TX_req; - nfapi_nr_ul_config_request_t *UL_req = Sched_INFO->UL_req; + nfapi_nr_dl_tti_request_t *DL_req = Sched_INFO->DL_req; + nfapi_nr_tx_data_request_t *TX_req = Sched_INFO->TX_req; + nfapi_nr_ul_tti_request_t *UL_tti_req = Sched_INFO->UL_tti_req; + nfapi_nr_ul_dci_request_t *UL_dci_req = Sched_INFO->UL_dci_req; frame_t frame = Sched_INFO->frame; sub_frame_t slot = Sched_INFO->slot; @@ -98,77 +145,68 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB = RC.gNB[Mod_id]; - uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; - uint8_t number_ul_pdu = UL_req->ul_config_request_body.number_pdu; + uint8_t number_dl_pdu = DL_req->dl_tti_request_body.nPDUs; + uint8_t number_ul_pdu = 0; + uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus; - + if (UL_tti_req != NULL) number_ul_pdu = UL_tti_req->n_pdus; - LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d \n", + LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d%d DL_req:SFN/SLO:%04d%d:dl_pdu:%d tx_req:SFN/SLOT:%04d%d:pdus:%d;\n", frame,slot, - NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu, - NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus); + DL_req->SFN,DL_req->Slot,number_dl_pdu, + TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs); int do_oai =0; int dont_send =0; - gNB->pdcch_vars.num_dci = 0; - gNB->pdcch_vars.num_pdsch_rnti = 0; - - gNB->pdcch_vars.num_dci=0; + int pdcch_received=0; + gNB->num_pdsch_rnti=0; + gNB->pdcch_pdu = NULL; + gNB->pbch_configured=0; for (int i=0;idl_config_request_body.dl_config_pdu_list[i]; - LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); - switch (dl_config_pdu->pdu_type) { - case NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE: - AssertFatal(dl_config_pdu->bch_pdu_rel15.pdu_index < TX_req->tx_request_body.number_of_pdus, - "bch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n", - dl_config_pdu->bch_pdu_rel15.pdu_index, - TX_req->tx_request_body.number_of_pdus); - gNB->pbch_configured=1; + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i]; + LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType); + switch (dl_tti_pdu->PDUType) { + case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: + gNB->pbch_configured=1; do_oai=1; - handle_nr_nfapi_bch_pdu(gNB, - dl_config_pdu, - TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu_rel15.pdu_index].segments[0].segment_data); + handle_nr_nfapi_ssb_pdu(gNB,frame,slot, + dl_tti_pdu); + break; - case NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE: - handle_nfapi_nr_dci_dl_pdu(gNB, - frame, slot, - &dl_config_pdu->dci_dl_pdu); - gNB->pdcch_vars.num_dci++; - gNB->pdcch_vars.num_pdsch_rnti++; + case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: + AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n"); + handle_nfapi_nr_pdcch_pdu(gNB, + frame, slot, + &dl_tti_pdu->pdcch_pdu); + + pdcch_received = 1; do_oai=1; break; - case NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE: + case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel15; - uint16_t pdu_index = dlsch_pdu_rel15->pdu_index; - uint16_t tx_pdus = TX_req->tx_request_body.number_of_pdus; - uint16_t invalid_pdu = pdu_index == -1; - uint8_t *sdu = invalid_pdu ? NULL : pdu_index >= tx_pdus ? NULL : TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data; - - AssertFatal(sdu!=NULL,"sdu is null, pdu_index %d, tx_pdus %d\n",pdu_index,tx_pdus); - handle_nr_nfapi_dlsch_pdu(gNB,frame,slot,&dl_config_pdu->dlsch_pdu, sdu); + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15; + uint16_t pduIndex = pdsch_pdu_rel15->pduIndex; + uint16_t tx_pdus = TX_req->Number_of_PDUs; + AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n", + pduIndex,TX_req->pdu_list[pduIndex].num_TLV); + uint8_t *sdu = TX_req->pdu_list[pduIndex].TLVs[0].value.direct; + handle_nr_nfapi_pdsch_pdu(gNB,frame,slot,&dl_tti_pdu->pdsch_pdu, sdu); do_oai=1; } } } + + if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t)); - if (nfapi_mode && do_oai && !dont_send) { - oai_nfapi_tx_req(Sched_INFO->TX_req); - - oai_nfapi_nr_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu + for (int i=0;iul_dci_pdu_list[i]); } - for (int i=0;iul_config_request_body.ul_config_pdu_list[i]; - LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type); - switch (ul_config_pdu->pdu_type) { - case NFAPI_NR_UL_CONFIG_ULSCH_PDU_TYPE: - //handle_nr_nfapi_ulsch_pdu(gNB,frame,slot,&ul_config_pdu->ulsch_pdu); - break; - } - } + } diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index 9157ca1632..c35ae82c0b 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -34,12 +34,16 @@ #include "PHY/phy_extern.h" #include "SCHED_NR/sched_nr.h" #include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO); -void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB, - int frame, int subframe, - nfapi_nr_dl_config_dci_dl_pdu *dcl_dl_pdu); -void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, - nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, + +void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB, + int frame, int subframe, + nfapi_nr_dl_tti_pdcch_pdu *dcl_dl_pdu); + +void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, uint8_t *sdu); +void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid); diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index 158fe38098..2c8abc4213 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -33,7 +33,7 @@ #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" #include "SCHED/sched_eNB.h" -#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "fapi_nr_l1.h" #include "nfapi_pnf.h" #include "common/utils/LOG/log.h" diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 0f348a9189..559244643d 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -34,7 +34,7 @@ #include "PHY/phy_extern.h" #include "sched_nr.h" #include "PHY/MODULATION/modulation_common.h" - +#include "PHY/MODULATION/nr_modulation.h" #include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if5_tools.h" @@ -56,189 +56,331 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int oai_exit; -void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols) { +void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - unsigned int aa,slot_offset,slot_offsetF; + unsigned int slot_offset,slot_offsetF; int slot = tti_tx; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); slot_offset = slot*fp->samples_per_slot; slot_offsetF = first_symbol*fp->ofdm_symbol_size; + if (first_symbol>0) slot_offset += (fp->ofdm_symbol_size*first_symbol) + (fp->nb_prefix_samples0) + (fp->nb_prefix_samples*(first_symbol-1)); LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d (first_symbol %d num_symbols %d)\n",ru->proc.frame_tx, ru->proc.tti_tx,slot,first_symbol,num_symbols); - for (aa=0; aanb_tx; aa++) { - if (fp->Ncp == 1) { + if (fp->Ncp == 1) { + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + num_symbols, + fp->nb_prefix_samples, + CYCLIC_PREFIX); + } + else { + if (first_symbol==0) { PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - num_symbols, - fp->nb_prefix_samples, - CYCLIC_PREFIX); + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + 1, + fp->nb_prefix_samples0, + CYCLIC_PREFIX); + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], + (int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size], + fp->ofdm_symbol_size, + num_symbols-1, + fp->nb_prefix_samples, + CYCLIC_PREFIX); } else { - if (first_symbol==0) { - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - 1, - fp->nb_prefix_samples0, - CYCLIC_PREFIX); - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], - (int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size], - fp->ofdm_symbol_size, - num_symbols-1, - fp->nb_prefix_samples, - CYCLIC_PREFIX); - } - else { - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - num_symbols, - fp->nb_prefix_samples, - CYCLIC_PREFIX); - } + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + num_symbols, + fp->nb_prefix_samples, + CYCLIC_PREFIX); } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0); } void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { - NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; - RU_proc_t *proc = &ru->proc; - struct timespec wait; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + RU_proc_t *proc = &ru->proc; + RU_feptx_t *feptx = proc->feptx; + + PHY_VARS_gNB *gNB; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + int slot = tti_tx; - wait.tv_sec=0; - wait.tv_nsec=5000000L; + int i = 0; + int j = 0;//symbol + int aa = 0;//physical antenna number + int ret = 0; + int ofdm_mask_full = (1<<(ru->nb_tx*2))-1; + int txdataF_offset = ((tti_tx%2)*fp->samples_per_slot_wCP); - start_meas(&ru->ofdm_mod_stats); + if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return; + for (aa=0; aanb_tx; aa++) memset(ru->common.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); - if (nr_slot_select(fp,frame_tx,slot) == SF_UL) return; + start_meas(&ru->ofdm_total_stats); - // this copy should be done in the precoding thread (currently inactive) - for (int aa=0;aanb_tx;aa++) - memcpy((void*)ru->common.txdataF_BF[aa], + //if (nr_slot_select(cfg,frame_tx,slot)==NR_DOWNLINK_SLOT) { + if(ru->num_gNB != 0){//L1 RU on same machine + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + for(j=0; j<2; ++j){//half slot + for(i=0; inb_tx; ++i){ + if(j == 0){ + AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i].aa = i; + feptx[i].index = i; + feptx[i].ru = ru; + feptx[i].symbol = 0; + feptx[i].slot = slot; + feptx[i].nb_antenna_ports = ru->nb_tx; + feptx[i].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + }//first half + else{ + AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i+ru->nb_tx].aa = i; + feptx[i+ru->nb_tx].index = i+ru->nb_tx; + feptx[i+ru->nb_tx].ru = ru; + feptx[i+ru->nb_tx].symbol = fp->symbols_per_slot>>1; + feptx[i+ru->nb_tx].slot = slot; + feptx[i+ru->nb_tx].nb_antenna_ports = ru->nb_tx; + feptx[i+ru->nb_tx].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + }//second half + }//physical antenna + }//half slot + }//if L1 RU on same machine + else{//(RU only machine) + for(j=0; jsymbols_per_slot; ++j){ - (void*)ru->gNB_list[0]->common_vars.txdataF[aa], fp->samples_per_slot_wCP*sizeof(int32_t)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1); + start_meas(&ru->txdataF_copy_stats); + if (ru->num_gNB == 1){ + gNB = ru->gNB_list[0]; + cfg = &gNB->gNB_config; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + for(i=0; inb_tx; ++i){ + memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size], + (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], + fp->ofdm_symbol_size*sizeof(int32_t)); + } - if (nr_slot_select(fp,frame_tx,slot)==SF_DL) { - // If this is not an S-tti - if (pthread_mutex_timedlock(&proc->mutex_feptx,&wait) != 0) { - printf("[RU] ERROR pthread_mutex_lock for feptx thread (IC %d)\n", proc->instance_cnt_feptx); - exit_fun( "error locking mutex_feptx" ); - return; - } - - if (proc->instance_cnt_feptx==0) { - printf("[RU] FEPtx thread busy\n"); - exit_fun("FEPtx thread busy"); - pthread_mutex_unlock( &proc->mutex_feptx ); - return; - } - - ++proc->instance_cnt_feptx; - // slot to pass to worker thread - proc->slot_feptx = slot; - pthread_mutex_unlock( &proc->mutex_feptx ); - - - if (pthread_cond_signal(&proc->cond_feptx) != 0) { - printf("[RU] ERROR pthread_cond_signal for feptx thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - + }//num_gNB == 1 + stop_meas(&ru->txdataF_copy_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + + if (nr_slot_select(cfg,slot,frame_tx)==SF_DL) { + // If this is not an S-tti + for(i=0; inb_tx; ++i){ + if(j%2 == 0){ + while(feptx[i].instance_cnt_feptx != -1){ + usleep(5); + } + AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i].aa = i; + feptx[i].index = i; + feptx[i].ru = ru; + feptx[i].symbol = j; + feptx[i].slot = slot; + feptx[i].nb_antenna_ports = ru->nb_tx; + feptx[i].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } + else{ + while(feptx[i+ru->nb_tx].instance_cnt_feptx != -1){ + usleep(5); + } + AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i+ru->nb_tx].aa = i; + feptx[i+ru->nb_tx].index = i+ru->nb_tx; + feptx[i+ru->nb_tx].ru = ru; + feptx[i+ru->nb_tx].symbol = j; + feptx[i+ru->nb_tx].slot = slot; + feptx[i+ru->nb_tx].nb_antenna_ports = ru->nb_tx; + feptx[i+ru->nb_tx].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } + } + }//if == SF_DL + else { + proc->feptx_mask = ofdm_mask_full; + } + }//jsymbols_per_slot + }//else (RU only machine) + //} + // wait all process to finish + AssertFatal((ret=pthread_mutex_lock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret); + while (proc->feptx_mask != ofdm_mask_full) { + // most of the time the thread is waiting here + // proc->instance_cnt_rxtx is -1 + pthread_cond_wait(&proc->cond_feptx,&proc->mutex_feptx); // this unlocks mutex_rxtx while waiting and then locks it again } + proc->feptx_mask = 0; + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret); - // call first half-slot in this thread - nr_feptx0(ru,slot,0,fp->symbols_per_slot>>1); - wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"NR feptx thread"); - + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, proc->feptx_mask ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); - //write_output - stop_meas(&ru->ofdm_mod_stats); + stop_meas(&ru->ofdm_total_stats); } static void *nr_feptx_thread(void *param) { - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; - - + RU_feptx_t *feptx = (RU_feptx_t *)param; + RU_t *ru; + int aa, slot, start, l, nb_antenna_ports, ret; + int i; + int32_t ***bw; + NR_DL_FRAME_PARMS *fp; + int ofdm_mask_full; + int txdataF_offset; + int32_t *txdataF; while (!oai_exit) { + ret = 0; + if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 1 ); - if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"NR feptx thread")<0) break; - int slot=proc->slot_feptx; - if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"NR feptx thread")<0) break; + AssertFatal(feptx->ru->nb_log_antennas>0 && feptx->ru->nb_log_antennas < 13,"ru->nb_log_antennas is %d\n", feptx->ru->nb_log_antennas); - nr_feptx0(ru,slot,ru->nr_frame_parms->symbols_per_slot>>1,ru->nr_frame_parms->symbols_per_slot>>1); + ru = feptx->ru; + slot = feptx->slot; + aa = feptx->aa; + l = feptx->symbol; + fp = ru->nr_frame_parms; + start = feptx->symbol; + nb_antenna_ports = feptx->nb_antenna_ports; + ofdm_mask_full = (1<<(ru->nb_tx*2))-1; - if (pthread_cond_signal(&proc->cond_feptx) != 0) { - LOG_E(PHY,"[gNB] ERROR pthread_cond_signal for NR feptx thread exit\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return NULL; - } - } + if(ru->num_gNB != 0){ + txdataF_offset = ((slot%2)*fp->samples_per_slot_wCP); + ////////////precoding//////////// + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); + start_meas(&ru->precoding_stats); + if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) { + memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], + (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], + (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); + } + else { + bw = ru->beam_weights[0]; + txdataF = &ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset]; + for(i=0; isymbols_per_slot>>1; ++i){ + nr_beam_precoding(&txdataF, + ru->common.txdataF_BF, + fp, + bw, + slot, + l+i, + aa, + nb_antenna_ports); + } + } + stop_meas(&ru->precoding_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); + + ////////////FEPTX//////////// + start_meas(&ru->ofdm_mod_stats); + nr_feptx0(ru,slot,start,fp->symbols_per_slot>>1,aa); + stop_meas(&ru->ofdm_mod_stats); + + if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; + + AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); + ru->proc.feptx_mask |= 1<<(feptx->index); + if(ru->proc.feptx_mask == ofdm_mask_full) + AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); + AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); + }// if L1 RU on same machine + + else{ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); + start_meas(&ru->precoding_stats); + if (ru->nb_tx == 1 && ru->nb_log_antennas) { + memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], + (void*)&ru->common.txdataF[0][l*fp->ofdm_symbol_size], + fp->ofdm_symbol_size*sizeof(int32_t)); + } + else { + bw = ru->beam_weights[0]; + nr_beam_precoding(ru->common.txdataF, + ru->common.txdataF_BF, + fp, + bw, + slot, + l, + aa, + nb_antenna_ports); + } + stop_meas(&ru->precoding_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); + + + start_meas(&ru->ofdm_mod_stats); + nr_feptx0(ru,slot,start,1,aa); + stop_meas(&ru->ofdm_mod_stats); + + if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; + + if(l >= fp->symbols_per_slot -2){ + AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); + ru->proc.feptx_mask |= 1<<(feptx->index); + if(ru->proc.feptx_mask == ofdm_mask_full) + AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); + AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); + }// else (RU only machine) + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 0 ); + }// while (oai_exit) return(NULL); } -void nr_init_feptx_thread(RU_t *ru) { - - RU_proc_t *proc = &ru->proc; - - proc->instance_cnt_feptx = -1; - - pthread_mutex_init( &proc->mutex_feptx, NULL); - pthread_cond_init( &proc->cond_feptx, NULL); - - threadCreate(&proc->pthread_feptx, nr_feptx_thread, (void*)ru, "feptx", -1, OAI_PRIORITY_RT); - - -} // is this supposed to generate a slot or a subframe??? // seems to be hardcoded to numerology 1 (2 slots=1 subframe) void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; + int cyclic_prefix_type = NFAPI_CP_NORMAL; unsigned int aa=0; int slot_sizeF = (fp->ofdm_symbol_size)* - ((cfg->subframe_config.dl_cyclic_prefix_type.value == 1) ? 12 : 14); + ((cyclic_prefix_type == 1) ? 12 : 14); int slot = tti_tx; int *txdata = &ru->common.txdata[aa][slot*fp->samples_per_slot]; + if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); start_meas(&ru->ofdm_mod_stats); - // this copy should be done in the precoding thread (currently inactive) - for (int aa=0;aanb_tx;aa++) - memcpy((void*)ru->common.txdataF_BF[aa], - (void*)ru->gNB_list[0]->common_vars.txdataF[aa], fp->samples_per_slot_wCP*sizeof(int32_t)); - if ((nr_slot_select(fp,frame_tx,slot)==SF_DL)|| - ((nr_slot_select(fp,frame_tx,slot)==SF_S))) { // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); - nr_feptx0(ru,slot,0,fp->symbols_per_slot); - - } + nr_feptx0(ru,slot,0,NR_NUMBER_OF_SYMBOLS_PER_SLOT,aa); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); stop_meas(&ru->ofdm_mod_stats); @@ -249,12 +391,246 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { } -void nr_feprx(RU_t *ru) { +void nr_init_feptx_thread(RU_t *ru) { + + RU_proc_t *proc = &ru->proc; + RU_feptx_t *feptx = proc->feptx; + int i = 0; + + for(i=0; i<(ru->nb_tx*2); i++){ + feptx[i].instance_cnt_feptx = -1; + + pthread_mutex_init( &feptx[i].mutex_feptx, NULL); + pthread_cond_init( &feptx[i].cond_feptx, NULL); + + threadCreate(&feptx[i].pthread_feptx, nr_feptx_thread, (void*)&feptx[i], "feptx", -1, OAI_PRIORITY_RT); + LOG_I(PHY,"init feptx thread %d\n", i); + } - // PRACH component - int frame=ru->proc.frame_rx, slot=ru->proc.tti_rx; - - if (do_prach_rx(ru->nr_frame_parms,frame,slot)) rx_nr_prach_ru(ru, - frame, - slot/ru->nr_frame_parms->slots_per_subframe); +} + + +void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) { + + int l,aa; + PHY_VARS_gNB **gNB_list = ru->gNB_list,*gNB; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + int32_t ***bw; + int i=0; + int slot_tx = tti_tx; + int txdataF_offset = ((tti_tx%2)*fp->samples_per_slot_wCP); + + start_meas(&ru->precoding_stats); + AssertFatal(ru->nb_log_antennas > 0,"ru->nb_log_antennas is 0!\n"); + if (ru->num_gNB == 1){ + gNB = gNB_list[0]; + + if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT) return; + + for(i=0; inb_log_antennas; ++i) + memcpy((void*)ru->common.txdataF[i], + (void*)&gNB->common_vars.txdataF[i][txdataF_offset], + fp->samples_per_slot_wCP*sizeof(int32_t)); + + if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) { + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + + memcpy((void*)ru->common.txdataF_BF[0], + (void*)ru->common.txdataF[0], + fp->samples_per_slot_wCP*sizeof(int32_t)); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); + }// if (ru->nb_tx == 1) + else { + bw = ru->beam_weights[0]; + for (l=0;lsymbols_per_slot;l++) { + for (aa=0;aanb_tx;aa++) { + nr_beam_precoding(ru->common.txdataF, + ru->common.txdataF_BF, + fp, + bw, + tti_tx, + l, + aa, + ru->nb_log_antennas); + }// for (aa=0;aanb_tx;aa++) + }// for (l=0;lsymbols_per_slot;l++) + }// if (ru->nb_tx == 1) + }// if (ru->num_gNB == 1) + stop_meas(&ru->precoding_stats); +} + +void nr_fep0(RU_t *ru, int first_half) { + + uint8_t start_symbol, end_symbol, l, aa; + RU_proc_t *proc = &ru->proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + + if(first_half == 1) { + start_symbol = 0; + end_symbol = NR_SYMBOLS_PER_SLOT/2; + } else { + start_symbol = NR_SYMBOLS_PER_SLOT/2; + end_symbol = NR_SYMBOLS_PER_SLOT; + } + + LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d\n", proc->tti_rx, first_half, start_symbol, end_symbol); + // printf("fep0: slot %d\n",slot); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 1); + + // remove_7_5_kHz(ru,(slot&1)+(proc->tti_rx<<1)); + for (l = start_symbol; l < end_symbol; l++) { + for (aa = 0; aa < fp->nb_antennas_rx; aa++) { + nr_slot_fep_ul(fp, + ru->common.rxdata[aa], + ru->common.rxdataF[aa], + l, + proc->tti_rx, + 0, + 0); + } + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0); +} + + +static void *nr_feprx_thread(void *param) { + + RU_t *ru = (RU_t *)param; + RU_proc_t *proc = &ru->proc; + + + while (!oai_exit) { + + if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"NR feprx thread")<0) break; + + if (oai_exit) break; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 ); + + nr_fep0(ru, 0); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 ); + + if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"nr_feprx thread")<0) break; + + if (pthread_cond_signal(&proc->cond_fep) != 0) { + printf("[gNB] ERROR pthread_cond_signal for nr_feprx thread exit\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return NULL; + } + } + + return NULL; +} + + +void nr_init_feprx_thread(RU_t *ru) { + + RU_proc_t *proc = &ru->proc; + + proc->instance_cnt_fep = -1; + + pthread_mutex_init( &proc->mutex_fep, NULL); + pthread_cond_init( &proc->cond_fep, NULL); + + threadCreate(&proc->pthread_fep, nr_feprx_thread, (void*)ru, "feprx", -1, OAI_PRIORITY_RT); +} + + +void nr_fep_full_2thread(RU_t *ru, int slot) { + + RU_proc_t *proc = &ru->proc; + + struct timespec wait; + + // NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + + // if ((fp->frame_type == TDD) && + // (subframe_select(fp,proc->tti_rx) != NR_UPLINK_SLOT)) return; + + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); + + wait.tv_sec=0; + wait.tv_nsec=5000000L; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); + start_meas(&ru->ofdm_demod_stats); + + if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) { + printf("[RU] ERROR pthread_mutex_lock for nr_feprx thread (IC %d)\n", proc->instance_cnt_fep); + exit_fun( "error locking mutex_fep" ); + return; + } + + if (proc->instance_cnt_fep==0) { + printf("[RU] FEP thread busy\n"); + exit_fun("FEP thread busy"); + pthread_mutex_unlock( &proc->mutex_fep ); + return; + } + + ++proc->instance_cnt_fep; + + + if (pthread_cond_signal(&proc->cond_fep) != 0) { + printf("[RU] ERROR pthread_cond_signal for nr_feprx thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return; + } + //start_meas(&ru->ofdm_demod_wakeup_stats); + + pthread_mutex_unlock( &proc->mutex_fep ); + + // call second slot in this symbol + nr_fep0(ru, 1); + + start_meas(&ru->ofdm_demod_wait_stats); + wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"nr_feprx thread"); + stop_meas(&ru->ofdm_demod_wait_stats); + if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){ + print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr); + printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->tti_rx); + } + + stop_meas(&ru->ofdm_demod_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); +} + + + +void nr_fep_full(RU_t *ru, int slot) { + + RU_proc_t *proc = &ru->proc; + int l, aa; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + + // if ((fp->frame_type == TDD) && + // (subframe_select(fp,proc->tti_rx) != NR_UPLINK_SLOT)) return; + + start_meas(&ru->ofdm_demod_stats); + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); + + // remove_7_5_kHz(ru,proc->tti_rx<<1); + // remove_7_5_kHz(ru,1+(proc->tti_rx<<1)); + + for (l = 0; l < fp->symbols_per_slot; l++) { + for (aa = 0; aa < fp->nb_antennas_rx; aa++) { + nr_slot_fep_ul(fp, + ru->common.rxdata[aa], + ru->common.rxdataF[aa], + l, + proc->tti_rx, + 0, + 0); + } + } + + if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); + stop_meas(&ru->ofdm_demod_stats); + + } diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index b171b2ac65..fa22e43661 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -32,6 +32,8 @@ #include "SCHED_NR_UE/defs.h" #include "PHY/defs_nr_UE.h" #include "SCHED_NR_UE/phy_frame_config_nr.h" +#include "PHY/impl_defs_nr.h" +#include "PHY/impl_defs_top.h" /******************************************************************* * @@ -49,56 +51,123 @@ * *********************************************************************/ -int set_tdd_config_nr(NR_DL_FRAME_PARMS *frame_parms, int dl_UL_TransmissionPeriodicity, +int set_tdd_config_nr( nfapi_nr_config_request_scf_t *cfg, + int mu, int nrofDownlinkSlots, int nrofDownlinkSymbols, - int nrofUplinkSlots, int nrofUplinkSymbols) -{ - TDD_UL_DL_configCommon_t *p_tdd_ul_dl_configuration; + int nrofUplinkSlots, int nrofUplinkSymbols) { int slot_number = 0; - int nb_slots_to_set = TDD_CONFIG_NB_FRAMES*(frame_parms->ttis_per_subframe * LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + int nb_periods_per_frame; + int nb_slots_to_set = TDD_CONFIG_NB_FRAMES*(1<tdd_table.tdd_period.value) { + case 0: + nb_periods_per_frame = 20; // 10ms/0p5ms + break; - if (p_tdd_ul_dl_configuration == NULL) { - printf("Error test_frame_configuration: memory allocation problem \n"); - assert(0); + case 1: + nb_periods_per_frame = 16; // 10ms/0p625ms + break; + + case 2: + nb_periods_per_frame = 10; // 10ms/1ms + break; + + case 3: + nb_periods_per_frame = 8; // 10ms/1p25ms + break; + + case 4: + nb_periods_per_frame = 5; // 10ms/2ms + break; + + case 5: + nb_periods_per_frame = 4; // 10ms/2p5ms + break; + + case 6: + nb_periods_per_frame = 2; // 10ms/5ms + break; + + case 7: + nb_periods_per_frame = 1; // 10ms/10ms + break; + + default: + AssertFatal(1==0,"Undefined tdd period %d\n", cfg->tdd_table.tdd_period.value); } + + int nb_slots_per_period = ((1<frame_type = TDD; + AssertFatal(nrofDownlinkSymbols + nrofUplinkSymbols < 14,"illegal symbol configuration DL %d, UL %d\n",nrofDownlinkSymbols,nrofUplinkSymbols); + AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots + 1), + "set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nrofMixed slots 1, nb_slots_per_period %d \n", + nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period); } - p_tdd_ul_dl_configuration->dl_UL_TransmissionPeriodicity = dl_UL_TransmissionPeriodicity; - p_tdd_ul_dl_configuration->nrofDownlinkSlots = nrofDownlinkSlots; - p_tdd_ul_dl_configuration->nrofDownlinkSymbols = nrofDownlinkSymbols; - p_tdd_ul_dl_configuration->nrofUplinkSlots = nrofUplinkSlots; - p_tdd_ul_dl_configuration->nrofUplinkSymbols = nrofUplinkSymbols; + cfg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_to_set*sizeof(nfapi_nr_max_tdd_periodicity_t)); - frame_parms->p_tdd_UL_DL_Configuration = p_tdd_ul_dl_configuration; - - int nb_periods_per_frame = (FRAME_DURATION_MICRO_SEC/dl_UL_TransmissionPeriodicity); - - int nb_slots_per_period = ((1<numerology_index) * LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)/nb_periods_per_frame; - - AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots + 1), - "set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, nrofUplinkSlots %d, nb_slots_per_period %d \n", - nrofDownlinkSlots,nrofUplinkSlots,nb_slots_per_period); - AssertFatal(nrofDownlinkSymbols + nrofUplinkSymbols < 14,"illegal symbol configuration DL %d, UL %d\n",nrofDownlinkSymbols,nrofUplinkSymbols); + for(int memory_alloc =0 ; memory_alloctdd_table.max_tdd_periodicity_list[memory_alloc].max_num_of_symbol_per_slot_list = (nfapi_nr_max_num_of_symbol_per_slot_t *) malloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT*sizeof( + nfapi_nr_max_num_of_symbol_per_slot_t)); while(slot_number != nb_slots_to_set) { + if(nrofDownlinkSlots != 0) { + for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { + cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value= 0; + + if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) + slot_number++; + } + } + + if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) { + for(int number_of_symbol =0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) { + cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config.value= 0; + } + + for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol++) { + cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config.value= 2; + } + + for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT-nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { + cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config.value= 1; + } - for (int number_of_slot = 0; number_of_slot < nrofDownlinkSlots; number_of_slot++) { - frame_parms->tdd_uplink_nr[slot_number] = NR_TDD_DOWNLINK_SLOT; slot_number++; } - if (p_tdd_ul_dl_configuration->nrofDownlinkSymbols != 0) { - LOG_E(PHY,"set_tdd_configuration_nr: downlink symbol for slot is not supported for tdd configuration \n"); - return (-1); + if(nrofUplinkSlots != 0) { + for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots*NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) { + cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol%NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value= 1; + + if((number_of_symbol+1)%NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) + slot_number++; + } + } + } + + /* + while(slot_number != nb_slots_to_set) { + for (int number_of_slot = 0; number_of_slot < nrofDownlinkSlots; number_of_slot++) { + frame_parms->tdd_uplink_nr[slot_number] = NR_TDD_DOWNLINK_SLOT; + printf("slot %d set as downlink\n",slot_number); + slot_number++; + } + + if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) { + frame_parms->tdd_uplink_nr[slot_number] = (1<tdd_uplink_nr[slot_number] = NR_TDD_UPLINK_SLOT; + printf("slot %d set as uplink\n",slot_number); slot_number++; } @@ -111,8 +180,7 @@ int set_tdd_config_nr(NR_DL_FRAME_PARMS *frame_parms, int dl_UL_TransmissionPeri if (frame_parms->p_tdd_UL_DL_ConfigurationCommon2 != NULL) { LOG_E(PHY,"set_tdd_configuration_nr: additionnal tdd configuration 2 is not supported for tdd configuration \n"); return (-1); - } - + }*/ return (0); } @@ -132,8 +200,7 @@ int set_tdd_config_nr(NR_DL_FRAME_PARMS *frame_parms, int dl_UL_TransmissionPeri * *********************************************************************/ -void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slotIndex, int nrofDownlinkSymbols, int nrofUplinkSymbols) -{ +void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slotIndex, int nrofDownlinkSymbols, int nrofUplinkSymbols) { TDD_UL_DL_SlotConfig_t *p_TDD_UL_DL_ConfigDedicated = frame_parms->p_TDD_UL_DL_ConfigDedicated; TDD_UL_DL_SlotConfig_t *p_previous_TDD_UL_DL_ConfigDedicated; int next = 0; @@ -145,6 +212,7 @@ void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slot } p_TDD_UL_DL_ConfigDedicated = calloc( 1, sizeof(TDD_UL_DL_SlotConfig_t)); + //printf("allocate pt %p \n", p_TDD_UL_DL_ConfigDedicated); if (p_TDD_UL_DL_ConfigDedicated == NULL) { printf("Error test_frame_configuration: memory allocation problem \n"); @@ -153,8 +221,7 @@ void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slot if (next == 0) { frame_parms->p_TDD_UL_DL_ConfigDedicated = p_TDD_UL_DL_ConfigDedicated; - } - else { + } else { p_previous_TDD_UL_DL_ConfigDedicated->p_next_TDD_UL_DL_SlotConfig = (struct TDD_UL_DL_SlotConfig_t *)p_TDD_UL_DL_ConfigDedicated; } @@ -179,55 +246,48 @@ void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slot * *********************************************************************/ -int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) -{ +int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { TDD_UL_DL_SlotConfig_t *p_current_TDD_UL_DL_SlotConfig; - p_current_TDD_UL_DL_SlotConfig = frame_parms->p_TDD_UL_DL_ConfigDedicated; - NR_TST_PHY_PRINTF("\nSet tdd dedicated configuration\n "); while(p_current_TDD_UL_DL_SlotConfig != NULL) { int slot_index = p_current_TDD_UL_DL_SlotConfig->slotIndex; - if (slot_index < TDD_CONFIG_NB_FRAMES*(frame_parms->ttis_per_subframe * LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) { + + if (slot_index < TDD_CONFIG_NB_FRAMES*(frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)) { if (p_current_TDD_UL_DL_SlotConfig->nrofDownlinkSymbols != 0) { if (p_current_TDD_UL_DL_SlotConfig->nrofDownlinkSymbols == NR_TDD_SET_ALL_SYMBOLS) { if (p_current_TDD_UL_DL_SlotConfig->nrofUplinkSymbols == 0) { frame_parms->tdd_uplink_nr[slot_index] = NR_TDD_DOWNLINK_SLOT; NR_TST_PHY_PRINTF(" DL[%d] ", slot_index); - } - else { + } else { LOG_E(PHY,"set_tdd_configuration_dedicated_nr: tdd downlink & uplink symbol configuration is not supported \n"); return (-1); } - } - else { + } else { LOG_E(PHY,"set_tdd_configuration_dedicated_nr: tdd downlink symbol configuration is not supported \n"); return (-1); } - } - else if (p_current_TDD_UL_DL_SlotConfig->nrofUplinkSymbols != 0) { + } else if (p_current_TDD_UL_DL_SlotConfig->nrofUplinkSymbols != 0) { if (p_current_TDD_UL_DL_SlotConfig->nrofUplinkSymbols == NR_TDD_SET_ALL_SYMBOLS) { frame_parms->tdd_uplink_nr[slot_index] = NR_TDD_UPLINK_SLOT; NR_TST_PHY_PRINTF(" UL[%d] ", slot_index); - } - else { + } else { LOG_E(PHY,"set_tdd_configuration_dedicated_nr: tdd uplink symbol configuration is not supported \n"); return (-1); } - } - else { + } else { LOG_E(PHY,"set_tdd_configuration_dedicated_nr: no tdd symbol configuration is specified \n"); return (-1); } - } - else { + } else { LOG_E(PHY,"set_tdd_configuration_dedicated_nr: tdd slot index exceeds maximum value \n"); return (-1); } p_current_TDD_UL_DL_SlotConfig = (TDD_UL_DL_SlotConfig_t *)(p_current_TDD_UL_DL_SlotConfig->p_next_TDD_UL_DL_SlotConfig); } + NR_TST_PHY_PRINTF("\n"); return (0); } @@ -250,26 +310,62 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) * *********************************************************************/ -int nr_slot_select(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti) -{ +int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) { /* for FFD all slot can be considered as an uplink */ - if (frame_parms->frame_type == FDD) { + int mu = cfg->ssb_config.scs_common.value,check_slot=0; + + if (cfg->cell_config.frame_duplex_type.value == FDD) { return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT ); } if (nr_frame%2 == 0) { - if (frame_parms->tdd_uplink_nr[nr_tti] == NR_TDD_UPLINK_SLOT) { + for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { + check_slot++; + } + } + + if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { return (NR_UPLINK_SLOT); } - else { + + check_slot = 0; + + for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { + check_slot++; + } + } + + if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { return (NR_DOWNLINK_SLOT); + } else { + return (NR_MIXED_SLOT); + } + } else { + for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_uplink_nr[(frame_parms->ttis_per_subframe * LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti] == NR_TDD_UPLINK_SLOT)) { - return (NR_UPLINK_SLOT); - } - else { - return (NR_DOWNLINK_SLOT); } } @@ -285,10 +381,8 @@ int nr_slot_select(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti) * *********************************************************************/ -void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms) -{ +void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms) { TDD_UL_DL_configCommon_t *p_tdd_UL_DL_Configuration = frame_parms->p_tdd_UL_DL_Configuration; - free_tdd_configuration_dedicated_nr(frame_parms); if (p_tdd_UL_DL_Configuration != NULL) { @@ -313,11 +407,11 @@ void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms) * *********************************************************************/ -void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) -{ +void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { TDD_UL_DL_SlotConfig_t *p_current_TDD_UL_DL_ConfigDedicated = frame_parms->p_TDD_UL_DL_ConfigDedicated; TDD_UL_DL_SlotConfig_t *p_next_TDD_UL_DL_ConfigDedicated; int next = 0; + if (p_current_TDD_UL_DL_ConfigDedicated != NULL) { do { if (p_current_TDD_UL_DL_ConfigDedicated->p_next_TDD_UL_DL_SlotConfig != NULL) { @@ -327,8 +421,7 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) //printf("free pt %p \n", p_current_TDD_UL_DL_ConfigDedicated); free(p_current_TDD_UL_DL_ConfigDedicated); p_current_TDD_UL_DL_ConfigDedicated = p_next_TDD_UL_DL_ConfigDedicated; - } - else { + } else { if (p_current_TDD_UL_DL_ConfigDedicated != NULL) { frame_parms->p_TDD_UL_DL_ConfigDedicated = NULL; //printf("free pt %p \n", p_current_TDD_UL_DL_ConfigDedicated); diff --git a/openair1/SCHED_NR/phy_frame_config_nr.h b/openair1/SCHED_NR/phy_frame_config_nr.h index 0f148cbafe..d1ec5c80d8 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.h +++ b/openair1/SCHED_NR/phy_frame_config_nr.h @@ -47,7 +47,7 @@ * @param nrofUplinkSymbols number of uplink symbols @returns 0 if tdd dedicated configuration has been properly set or -1 on error with message */ -int set_tdd_config_nr(NR_DL_FRAME_PARMS *frame_parms, int dl_UL_TransmissionPeriodicity, +int set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, int mu, int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSlots, int nrofUplinkSymbols); @@ -78,7 +78,7 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms); * @param nr_tti : slot number @returns nr_slot_t : downlink or uplink */ -nr_slot_t nr_slot_select(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti); +nr_slot_t nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti); /** \brief This function frees tdd configuration for nr * @param frame_parms NR DL Frame parameters diff --git a/openair1/SCHED_NR/phy_procedures_nr_common.c b/openair1/SCHED_NR/phy_procedures_nr_common.c index 97891f9db9..8d1f615569 100755 --- a/openair1/SCHED_NR/phy_procedures_nr_common.c +++ b/openair1/SCHED_NR/phy_procedures_nr_common.c @@ -31,4 +31,5 @@ */ #include "sched_nr.h" +#include "PHY/INIT/phy_init.h" diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 4a23c99ffa..f114ca5002 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -26,10 +26,13 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_ulsch.h" +#include "PHY/NR_ESTIMATION/nr_ul_estimation.h" #include "SCHED/sched_eNB.h" +#include "sched_nr.h" #include "SCHED/sched_common_extern.h" -#include "nfapi_interface.h" -#include "SCHED/fapi_l1.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h" +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" +#include "fapi_nr_l1.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/INIT/phy_init.h" @@ -81,64 +84,67 @@ int return_ssb_type(nfapi_config_request_t *cfg) -void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp) { - fp->ssb_start_subcarrier = (12 * cfg->sch_config.n_ssb_crb.value + cfg->sch_config.ssb_subcarrier_offset.value)/(1<subframe_config.numerology_index_mu.value); - LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->sch_config.n_ssb_crb.value,cfg->sch_config.ssb_subcarrier_offset.value); +void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp) { + fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + cfg->ssb_table.ssb_subcarrier_offset.value); + LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,cfg->ssb_table.ssb_subcarrier_offset.value); } void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; int **txdataF = gNB->common_vars.txdataF; - uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; uint8_t ssb_index, n_hf; int ssb_start_symbol, rel_slot; + int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; + uint16_t slots_per_hf = fp->slots_per_frame / 2; - n_hf = cfg->sch_config.half_frame_index.value; + n_hf = fp->half_frame_bit; // if SSB periodicity is 5ms, they are transmitted in both half frames - if ( cfg->sch_config.ssb_periodicity.value == 5) { - if (slot<10) + if ( cfg->ssb_table.ssb_period.value == 0) { + if (slot=0) { - for (int i=0; i<2; i++) { // max two SSB per frame - - ssb_index = i + 2*rel_slot; // computing the ssb_index - if ((fp->L_ssb >> ssb_index) & 0x01) { // generating the ssb only if the bit of L_ssb at current ssb index is 1 + for (int i=0; i<2; i++) { // max two SSB per frame + + ssb_index = i + 2*rel_slot; // computing the ssb_index + if ((fp->L_ssb >> ssb_index) & 0x01) { // generating the ssb only if the bit of L_ssb at current ssb index is 1 - int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp, ssb_index, n_hf); // computing the starting symbol for current ssb - ssb_start_symbol = ssb_start_symbol_abs % 14; // start symbol wrt slot - - nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier - - LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); - nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); - nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); - - if (fp->Lmax == 4) - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); - else - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); - - nr_generate_pbch(&gNB->pbch, - pbch_pdu, - gNB->nr_pbch_interleaver, - txdataF[0], - AMP, - ssb_start_symbol, - n_hf,fp->Lmax,ssb_index, - frame, cfg, fp); - } - } + gNB->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = ssb_index; + + int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp, ssb_index); // computing the starting symbol for current ssb + ssb_start_symbol = ssb_start_symbol_abs % 14; // start symbol wrt slot + + nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier + + LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); + nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); + nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); + + if (cfg->carrier_config.num_tx_ant.value <= 4) + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); + else + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); + + nr_generate_pbch(&gNB->pbch, + &gNB->ssb_pdu, + gNB->nr_pbch_interleaver, + &txdataF[0][txdataF_offset], + AMP, + ssb_start_symbol, + n_hf,cfg->carrier_config.num_tx_ant.value, + frame, cfg, fp); + } + } } } @@ -146,71 +152,76 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame,int slot, int do_meas) { int aa; - uint8_t num_dci=0,num_pdsch_rnti; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; int offset = gNB->CC_id; - uint8_t ssb_frame_periodicity; // every how many frames SSB are generated + uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated + int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; - if (cfg->sch_config.ssb_periodicity.value < 20) - ssb_frame_periodicity = 1; - else - ssb_frame_periodicity = (cfg->sch_config.ssb_periodicity.value)/10 ; // 10ms is the frame length + + + if (cfg->ssb_table.ssb_period.value > 1) + ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ; // 10ms is the frame length - if ((cfg->subframe_config.duplex_mode.value == TDD) && - ((nr_slot_select(fp,frame,slot)&NR_UPLINK_SLOT) > 0)) return; + if ((cfg->cell_config.frame_duplex_type.value == TDD) && + (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1); if (do_meas==1) start_meas(&gNB->phy_proc_tx); // clear the transmit data array for the current subframe - for (aa=0; aa<1/*15*/; aa++) { - memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); + for (aa=0; aacarrier_config.num_tx_ant.value; aa++) { + memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,1); if (nfapi_mode == 0 || nfapi_mode == 1) { - if (!(frame%ssb_frame_periodicity)) // generate SSB only for given frames according to SSB periodicity + if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity nr_common_signal_procedures(gNB,frame, slot); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,0); - num_dci = gNB->pdcch_vars.num_dci; - num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti; - if (num_dci) { - LOG_D(PHY, "[gNB %d] Frame %d slot %d \ - Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); - if (nfapi_mode == 0 || nfapi_mode == 1) { - nr_generate_dci_top(gNB->pdcch_vars, - gNB->nr_gold_pdcch_dmrs[slot], - gNB->common_vars.txdataF[0], - AMP, *fp, *cfg); + LOG_D(PHY, "[gNB %d] Frame %d slot %d \ + Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, gNB->pdcch_pdu->pdcch_pdu_rel15.numDlDci); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); + + if (gNB->pdcch_pdu || gNB->ul_dci_pdu) nr_generate_dci_top(gNB->pdcch_pdu, + gNB->ul_dci_pdu, + gNB->nr_gold_pdcch_dmrs[slot], + &gNB->common_vars.txdataF[0][txdataF_offset], + AMP, *fp); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); - if (num_pdsch_rnti) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); - LOG_D(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti); - nr_generate_pdsch(gNB->dlsch[0][0], - &gNB->pdcch_vars.dci_alloc[0], - gNB->nr_gold_pdsch_dmrs[slot], - gNB->common_vars.txdataF, - AMP, frame, slot, fp, cfg, - &gNB->dlsch_encoding_stats, - &gNB->dlsch_scrambling_stats, - &gNB->dlsch_modulation_stats); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); - } - } + + LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti); + for (int i=0; inum_pdsch_rnti; i++) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); + nr_generate_pdsch(gNB->dlsch[i][0], + gNB->nr_gold_pdsch_dmrs[slot], + gNB->common_vars.txdataF, + AMP, frame, slot, fp, 0, + &gNB->dlsch_encoding_stats, + &gNB->dlsch_scrambling_stats, + &gNB->dlsch_modulation_stats, + &gNB->tinput, + &gNB->tprep, + &gNB->tparity, + &gNB->toutput, + &gNB->dlsch_rate_matching_stats, + &gNB->dlsch_interleaving_stats, + &gNB->dlsch_segmentation_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0); } + /* if ((cfg->subframe_config.duplex_mode.value == TDD) && @@ -222,13 +233,13 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, if (do_prach_rx(fp,frame,slot)) L1_nr_prach_procedures(gNB,frame,slot/fp->slots_per_subframe); */ -void nr_ulsch_procedures(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int UE_id, uint8_t harq_pid) { - +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_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu; + nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu; nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &rel15_ul->ulsch_pdu_rel15; - //uint8_t ret; + uint8_t ret; uint32_t G; int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled) @@ -243,7 +254,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int UE_id, //------------------- ULSCH unscrambling ------------------- //---------------------------------------------------------- - nr_ulsch_unscrambling(gNB->pusch_vars[UE_id]->llr, + nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id]->llr, G, 0, Nid_cell, @@ -253,24 +264,93 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int UE_id, //--------------------- ULSCH decoding --------------------- //---------------------------------------------------------- - //ret = nr_ulsch_decoding(gNB, - nr_ulsch_decoding(gNB, - UE_id, - gNB->pusch_vars[UE_id]->llr, + ret = nr_ulsch_decoding(gNB, + ULSCH_id, + gNB->pusch_vars[ULSCH_id]->llr, frame_parms, - proc->frame_rx, + frame_rx, nfapi_ulsch_pdu_rel15->number_symbols, - proc->slot_rx, + slot_rx, harq_pid, 0); - // if (ret > ulsch_gNB->max_ldpc_iterations) - // n_errors++; + if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations) + LOG_I(PHY, "ULSCH in error\n"); + else + LOG_I(PHY, "ULSCH received ok\n"); } -void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) { +void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid) +{ + // -------------------- + // [hna] TO BE CLEANED + // -------------------- + + // nfapi_rx_indication_pdu_t *pdu; + + int timing_advance_update; + int sync_pos; + + // pthread_mutex_lock(&gNB->UL_INFO_mutex); + + // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx; + // gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + + // pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; + + // pdu->rx_ue_information.handle = gNB->ulsch[UE_id+1][0]->handle; + // pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; + // pdu->rx_ue_information.rnti = gNB->ulsch[UE_id+1][0]->rnti; + // pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; + // pdu->rx_indication_rel8.length = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->TBS>>3; + // pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation + // pdu->data = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b; + // estimate timing advance for MAC + sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); + timing_advance_update = sync_pos; // - gNB->frame_parms.nb_prefix_samples/4; //to check + // printf("\x1B[33m" "timing_advance_update = %d\n" "\x1B[0m", timing_advance_update); + + switch (gNB->frame_parms.N_RB_DL) { + // case 6: /* nothing to do */ break; + // case 15: timing_advance_update /= 2; break; + // case 25: timing_advance_update /= 4; break; + // case 50: timing_advance_update /= 8; break; + // case 75: timing_advance_update /= 12; break; + case 106: timing_advance_update /= 16; break; + case 217: timing_advance_update /= 32; break; + case 273: timing_advance_update /= 32; break; + default: abort(); + } + + // put timing advance command in 0..63 range + timing_advance_update += 31; + + if (timing_advance_update < 0) timing_advance_update = 0; + if (timing_advance_update > 63) timing_advance_update = 63; + + // pdu->rx_indication_rel8.timing_advance = timing_advance_update; + + // estimate UL_CQI for MAC (from antenna port 0 only) + // int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(10*gNB->measurements.n0_power_dB[0]); + + // if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0; + // else if (SNRtimes10 > 635) pdu->rx_indication_rel8.ul_cqi=255; + // else pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5; + + // LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n", + // harq_pid,frame,slot_rx,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, + // timing_advance_update); + + // gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; + // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | slot_rx; + + // pthread_mutex_unlock(&gNB->UL_INFO_mutex); +} + + +void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { uint8_t symbol; unsigned char aa; @@ -282,7 +362,7 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) { gNB->common_vars.rxdata[aa], gNB->common_vars.rxdataF[aa], symbol, - proc->slot_rx, + slot_rx, 0, 0); } @@ -290,25 +370,36 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) { } +void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { -void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end) { + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; + int num_pusch_pdu = UL_tti_req->n_pdus; + + LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pusch_pdu %d\n",frame_rx,slot_rx,num_pusch_pdu); - uint8_t UE_id; - uint8_t symbol; - uint8_t harq_pid = 0; // [hna] Previously in LTE, the harq_pid was obtained from the subframe number (Synchronous HARQ) - // In NR, this should be signaled through uplink scheduling dci (i.e, DCI 0_0, 0_1) (Asynchronous HARQ) + for (int i = 0; i < num_pusch_pdu; i++) { - for (UE_id = 0; UE_id < NUMBER_OF_NR_UE_MAX; UE_id++) { - - for(symbol = symbol_start; symbol < symbol_end; symbol++) { - - nr_rx_pusch(gNB, UE_id, proc->frame_rx, proc->slot_rx, symbol, harq_pid); + switch (UL_tti_req->pdus_list[i].pdu_type) { + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + { + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; + nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); + + uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST); + uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id; + uint8_t symbol_start = pusch_pdu->start_symbol_index; + uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols; + + for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { + nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); + } + //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[UE_id]->rxdataF_comp[0],6900,1,1); + //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[UE_id]->rxdataF_ext[0],6900,1,1); + nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); + nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC + } } - - nr_ulsch_procedures(gNB, proc, UE_id, harq_pid); - } - - } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 3f4c1b6f6d..5f54539b71 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -35,29 +35,23 @@ #include "phy_frame_config_nr.h" -void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp); +void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp); void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas); -void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc); -void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end); +void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); +void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); -void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols); +void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); void nr_init_feptx_thread(RU_t *ru); void fep_full(RU_t *ru,int slot); +void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx); +void nr_init_feptx_prec_thread(RU_t *ru); +void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx); +void nr_init_feprx_thread(RU_t *ru); +void nr_fep_full(RU_t *ru, int slot); +void nr_fep_full_2thread(RU_t *ru, int slot); void feptx_prec(RU_t *ru,int frame_tx,int tti_tx); int nr_phy_init_RU(RU_t *ru); -void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, - nr_scs_e scs_common, - nr_scs_e pdcch_scs, - nr_frequency_range_e freq_range, - uint8_t rmsi_pdcch_config, - uint8_t ssb_idx, - uint8_t k_ssb, - uint16_t sfn_ssb, - uint8_t n_ssb, - uint16_t nb_slots_per_frame, - uint16_t N_RB); - #endif diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 7b6c16b97d..e1f1ea0f42 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -121,10 +121,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t e @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 */ - -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, - fapi_nr_dl_config_request_t *DLconfigreq); +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_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); @@ -373,11 +370,10 @@ void nr_compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsP void set_tx_harq_id(NR_UE_ULSCH_t *ulsch, int harq_pid, int slot_tx); int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx); - +int is_pbch_in_slot(fapi_nr_pbch_config_t *pbch_config, int frame, int slot, int periodicity, uint16_t slots_per_frame); /*@}*/ #endif - diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 120e26aa31..b8c6412238 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -42,17 +42,19 @@ extern PHY_VARS_NR_UE ***PHY_vars_UE_g; int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) { - /// module id - module_id_t module_id = scheduled_response->module_id; - /// component carrier id - uint8_t cc_id = scheduled_response->CC_id; - uint32_t i; - int slot = scheduled_response->slot; + if(scheduled_response != NULL){ + /// module id + module_id_t module_id = scheduled_response->module_id; + /// component carrier id + uint8_t cc_id = scheduled_response->CC_id; + uint32_t i; + int slot = scheduled_response->slot; + // Note: we have to handle the thread IDs for this. To be revisited completely. uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; - NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; + NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0]; NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0]; //NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms; @@ -64,40 +66,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) if(scheduled_response->dl_config != NULL){ fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config; + LOG_D(PHY,"Received %d DL pdus\n",dl_config->number_pdus); + pdcch_vars->nb_search_space = 0; for(i=0; inumber_pdus; ++i){ if(dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI){ - pdcch_vars2->nb_search_space = pdcch_vars2->nb_search_space + 1; - fapi_nr_dl_config_dci_dl_pdu_rel15_t *dci_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15; - - pdcch_vars2->n_RB_BWP[i] = dci_config->N_RB_BWP; - pdcch_vars2->searchSpace[i].monitoringSymbolWithinSlot = dci_config->monitoring_symbols_within_slot; - - pdcch_vars2->searchSpace[i].nrofCandidates_aggrlevel1 = dci_config->number_of_candidates[0]; - pdcch_vars2->searchSpace[i].nrofCandidates_aggrlevel2 = dci_config->number_of_candidates[1]; - pdcch_vars2->searchSpace[i].nrofCandidates_aggrlevel4 = dci_config->number_of_candidates[2]; - pdcch_vars2->searchSpace[i].nrofCandidates_aggrlevel8 = dci_config->number_of_candidates[3]; - pdcch_vars2->searchSpace[i].nrofCandidates_aggrlevel16 = dci_config->number_of_candidates[4]; - - pdcch_vars2->coreset[i].duration = dci_config->coreset.duration; - - pdcch_vars2->coreset[i].frequencyDomainResources = dci_config->coreset.frequency_domain_resource; - pdcch_vars2->coreset[i].rb_offset = dci_config->coreset.rb_offset; - - if(dci_config->coreset.cce_reg_mapping_type == CCE_REG_MAPPING_TYPE_INTERLEAVED){ - pdcch_vars2->coreset[i].cce_reg_mappingType.shiftIndex = dci_config->coreset.cce_reg_interleaved_shift_index; - pdcch_vars2->coreset[i].cce_reg_mappingType.reg_bundlesize = dci_config->coreset.cce_reg_interleaved_reg_bundle_size; - pdcch_vars2->coreset[i].cce_reg_mappingType.interleaversize = dci_config->coreset.cce_reg_interleaved_interleaver_size; - }else{ //CCE_REG_MAPPING_TYPE_NON_INTERLEAVED - pdcch_vars2->coreset[i].cce_reg_mappingType.shiftIndex = 0; - pdcch_vars2->coreset[i].cce_reg_mappingType.reg_bundlesize = 6; - pdcch_vars2->coreset[i].cce_reg_mappingType.interleaversize = 1; - } - - pdcch_vars2->coreset[i].precoderGranularity = dci_config->coreset.precoder_granularity; - //pdcch_vars2->coreset[i].tciStatesPDCCH; - //pdcch_vars2->coreset[i].tciPresentInDCI; - pdcch_vars2->coreset[i].pdcchDMRSScramblingID = dci_config->coreset.pdcch_dmrs_scrambling_id; - + fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15; + memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config)); + pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1; + LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space); }else{ //FAPI_NR_DL_CONFIG_TYPE_DLSCH // dlsch config pdu @@ -111,11 +87,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid]; - + dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart; + dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize; dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs; dlsch0_harq->start_rb = dlsch_config_pdu->start_rb; dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols; dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol; + dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos; + dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType; dlsch0_harq->mcs = dlsch_config_pdu->mcs; dlsch0_harq->DCINdi = dlsch_config_pdu->ndi; dlsch0_harq->rvidx = dlsch_config_pdu->rv; @@ -123,66 +102,68 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id; dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind; dlsch0_harq->Nl=1; + dlsch0_harq->mcs_table=0; dlsch0_harq->status = ACTIVE; LOG_D(MAC,">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq->mcs); } } }else{ - pdcch_vars2->nb_search_space = 0; + pdcch_vars->nb_search_space = 0; } if(scheduled_response->ul_config != NULL){ fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config; for(i=0; inumber_pdus; ++i){ - if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_ULSCH){ + if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH){ // pusch config pdu - fapi_nr_ul_config_ulsch_pdu_rel15_t *ulsch_config_pdu = &ul_config->ul_config_list[i].ulsch_config_pdu.ulsch_pdu_rel15; - uint8_t current_harq_pid = ulsch_config_pdu->harq_process_nbr; - ulsch0->harq_processes[current_harq_pid]->nb_rb = ulsch_config_pdu->number_rbs; - ulsch0->harq_processes[current_harq_pid]->first_rb = ulsch_config_pdu->start_rb; - ulsch0->harq_processes[current_harq_pid]->number_of_symbols = ulsch_config_pdu->number_symbols; - ulsch0->harq_processes[current_harq_pid]->start_symbol = ulsch_config_pdu->start_symbol; - ulsch0->harq_processes[current_harq_pid]->mcs = ulsch_config_pdu->mcs; - ulsch0->harq_processes[current_harq_pid]->DCINdi = ulsch_config_pdu->ndi; - ulsch0->harq_processes[current_harq_pid]->rvidx = ulsch_config_pdu->rv; - ulsch0->f_pusch = ulsch_config_pdu->absolute_delta_PUSCH; + fapi_nr_ul_config_pusch_pdu_rel15_t *pusch_config_pdu = &ul_config->ul_config_list[i].ulsch_config_pdu.ulsch_pdu_rel15; + uint8_t current_harq_pid = pusch_config_pdu->harq_process_nbr; + ulsch0->harq_processes[current_harq_pid]->nb_rb = pusch_config_pdu->number_rbs; + ulsch0->harq_processes[current_harq_pid]->first_rb = pusch_config_pdu->start_rb; + ulsch0->harq_processes[current_harq_pid]->number_of_symbols = pusch_config_pdu->number_symbols; + ulsch0->harq_processes[current_harq_pid]->start_symbol = pusch_config_pdu->start_symbol; + ulsch0->harq_processes[current_harq_pid]->mcs = pusch_config_pdu->mcs; + ulsch0->harq_processes[current_harq_pid]->DCINdi = pusch_config_pdu->ndi; + ulsch0->harq_processes[current_harq_pid]->rvidx = pusch_config_pdu->rv; + ulsch0->harq_processes[current_harq_pid]->Nl = pusch_config_pdu->n_layers; + ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; } - if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_UCI){ + if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUCCH){ // pucch config pdu - fapi_nr_ul_config_uci_pdu *uci_config_pdu = &ul_config->ul_config_list[i].uci_config_pdu; + fapi_nr_ul_config_pucch_pdu *pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu; uint8_t pucch_resource_id = 0; //FIXME!!! uint8_t format = 1; // FIXME!!! - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = uci_config_pdu->initialCyclicShift; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = uci_config_pdu->nrofSymbols; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = uci_config_pdu->startingSymbolIndex; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = uci_config_pdu->nrofPRBs; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->startingPRB = uci_config_pdu->startingPRB; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = uci_config_pdu->timeDomainOCC; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = uci_config_pdu->occ_length; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = uci_config_pdu->occ_Index; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = uci_config_pdu->intraSlotFrequencyHopping; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->secondHopPRB = uci_config_pdu->secondHopPRB; // Not sure this parameter is used - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->additionalDMRS = uci_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->pi2PBSK = uci_config_pdu->pi2PBSK; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].pucch_GroupHopping = uci_config_pdu->pucch_GroupHopping; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].hoppingId = uci_config_pdu->hoppingId; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].p0_nominal = uci_config_pdu->p0_nominal; - /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = uci_config_pdu->initialCyclicShift; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = uci_config_pdu->nrofSymbols; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = uci_config_pdu->startingSymbolIndex; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = uci_config_pdu->nrofPRBs; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = uci_config_pdu->startingPRB; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = uci_config_pdu->timeDomainOCC; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = uci_config_pdu->occ_length; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = uci_config_pdu->occ_Index; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = uci_config_pdu->intraSlotFrequencyHopping; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = uci_config_pdu->secondHopPRB; // Not sure this parameter is used - pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = uci_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used - pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = uci_config_pdu->pi2PBSK; - pucch_config_common->pucch_GroupHopping = uci_config_pdu->pucch_GroupHopping; - pucch_config_common->hoppingId = uci_config_pdu->hoppingId; - pucch_config_common->p0_nominal = uci_config_pdu->p0_nominal;*/ + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used + PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].hoppingId = pucch_config_pdu->hoppingId; + PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].p0_nominal = pucch_config_pdu->p0_nominal; + /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used + pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used + pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK; + pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping; + pucch_config_common->hoppingId = pucch_config_pdu->hoppingId; + pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/ } if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PRACH){ // prach config pdu @@ -212,17 +193,41 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){ - fapi_nr_config_request_t nrUE_config = PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; + fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; if(phy_config != NULL){ - LOG_I(MAC,"[L1][IF module][PHY CONFIG]\n"); - LOG_I(MAC,"subcarrier spacing: %d\n", phy_config->config_req.rf_config.dl_subcarrierspacing); - LOG_I(MAC,"ssb carrier offset: %d\n", phy_config->config_req.sch_config.ssb_subcarrier_offset); - LOG_I(MAC,"dmrs TypeA Position: %d\n", phy_config->config_req.pdsch_config.dmrs_TypeA_Position); - LOG_I(MAC,"controlResourceSetZero: %d\n", phy_config->config_req.pdcch_config.controlResourceSetZero); - LOG_I(MAC,"searchSapceZero: %d\n", phy_config->config_req.pdcch_config.searchSpaceZero); - - LOG_I(MAC,"-------------------------------\n"); + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_PBCH){ + LOG_I(MAC,"[L1][IF module][PHY CONFIG]\n"); + LOG_I(MAC,"subcarrier spacing: %d\n", phy_config->config_req.pbch_config.subcarrier_spacing_common); + LOG_I(MAC,"ssb carrier offset: %d\n", phy_config->config_req.pbch_config.ssb_subcarrier_offset); + LOG_I(MAC,"dmrs type A position: %d\n", phy_config->config_req.pbch_config.dmrs_type_a_position); + LOG_I(MAC,"pdcch config sib1: %d\n", phy_config->config_req.pbch_config.pdcch_config_sib1); + LOG_I(MAC,"cell barred: %d\n", phy_config->config_req.pbch_config.cell_barred); + LOG_I(MAC,"intra frequency reselection: %d\n", phy_config->config_req.pbch_config.intra_frequency_reselection); + LOG_I(MAC,"system frame number: %d\n", phy_config->config_req.pbch_config.system_frame_number); + LOG_I(MAC,"ssb index: %d\n", phy_config->config_req.pbch_config.ssb_index); + LOG_I(MAC,"half frame bit: %d\n", phy_config->config_req.pbch_config.half_frame_bit); + LOG_I(MAC,"-------------------------------\n"); + + memcpy(&nrUE_config->pbch_config,&phy_config->config_req.pbch_config,sizeof(fapi_nr_pbch_config_t)); + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_COMMON){ + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_COMMON){ + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_DEDICATED){ + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_DEDICATED){ + + } } @@ -230,3 +235,4 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){ return 0; } + diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h index 429dff221b..309b695585 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h @@ -45,7 +45,7 @@ * @param nrofUplinkSymbols number of uplink symbols @returns 0 if tdd dedicated configuration has been properly set or -1 on error with message */ -int set_tdd_config_nr(NR_DL_FRAME_PARMS *frame_parms, int dl_UL_TransmissionPeriodicity, +int set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, int mu, int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSlots, int nrofUplinkSymbols); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 9758e1bc3e..d3c0f9e291 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -94,30 +94,15 @@ char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; extern double cpuf; + int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, uint32_t frame, - uint8_t nr_tti_rx, - uint8_t eNB_id, - MIMO_mode_t mimo_mode, - uint32_t high_speed_flag, - uint8_t is_secondary_ue, - int nb_coreset_active, - uint16_t symbol_mon, - NR_SEARCHSPACE_TYPE_t searchSpaceType); + uint32_t slot); -uint8_t nr_dci_decoding_procedure(int s, - int p, - PHY_VARS_NR_UE *ue, - NR_DCI_ALLOC_t *dci_alloc, - NR_SEARCHSPACE_TYPE_t searchSpacetype, - int16_t eNB_id, - uint8_t nr_tti_rx, - uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - crc_scrambled_t *crc_scrambled, - format_found_t *format_found, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]); +uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, + int frame, + int nr_tti_rx, + fapi_nr_dci_indication_t *dci_ind); /* int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, @@ -1427,137 +1412,6 @@ void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_ } -void ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) { - - int frame_tx = proc->frame_tx; - int nr_tti_tx = proc->nr_tti_tx; - int prach_power; - PRACH_RESOURCES_t prach_resources_local; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); - - ue->generate_prach=0; - - if (ue->mac_enabled==0){ - ue->prach_resources[eNB_id] = &prach_resources_local; - prach_resources_local.ra_RNTI = 0xbeef; - prach_resources_local.ra_PreambleIndex = 0; - } - - if (ue->mac_enabled==1){ - // ask L2 for RACH transport - if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { - LOG_D(PHY,"Getting PRACH resources\n"); - //ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id, - ue->CC_id, - frame_tx, - eNB_id, - nr_tti_tx); - LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); - LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]); - } -} - -if (ue->prach_resources[eNB_id]!=NULL) { - - ue->generate_prach=1; - ue->prach_cnt=0; -#ifdef SMBV - ue->prach_resources[eNB_id]->ra_PreambleIndex = 19; -#endif -#ifdef OAI_EMU - ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex; -#endif - - if (abstraction_flag == 0) { - - LOG_I(PHY,"mode %d\n",mode); - - if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) { - ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id); - } - else { - ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm; - ue->prach_resources[eNB_id]->ra_PreambleIndex = 19; - } - - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", - ue->Mod_id, - frame_tx, - nr_tti_tx, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - get_nr_PL(ue,eNB_id), - ue->tx_power_dBm[nr_tti_tx], - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, - ue->prach_resources[eNB_id]->ra_TDD_map_index, - ue->prach_resources[eNB_id]->ra_RNTI); - - ue->tx_total_RE[nr_tti_tx] = 96; - -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 6); -#else - ue->prach_vars[eNB_id]->amp = AMP; -#endif - if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) - LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n", - ue->Mod_id, - proc->frame_rx, - proc->nr_tti_tx, - ue->tx_power_dBm[nr_tti_tx], - ue->prach_vars[eNB_id]->amp); - - - // start_meas(&ue->tx_prach); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); - prach_power = generate_prach(ue,eNB_id,nr_tti_tx,frame_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); - // stop_meas(&ue->tx_prach); - LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", - ue->Mod_id, - get_nr_PL(ue,eNB_id), - ue->tx_power_dBm[nr_tti_tx], - dB_fixed(prach_power), - ue->prach_vars[eNB_id]->amp); - } else { - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1; - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex; - } - - if (ue->mac_enabled==1){ - //mac_xface->Msg1_transmitted(ue->Mod_id, - ue->CC_id, - frame_tx, - eNB_id); - } - -LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", - ue->Mod_id,frame_tx,nr_tti_tx,eNB_id, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id), - get_nr_PL(ue,eNB_id)); - -} - - -// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue -if (mode == calib_prach_tx) - ue->prach_resources[eNB_id]=NULL; - -LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_prach %d, prach_cnt %d\n", - ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_prach,ue->prach_cnt); - -ue->prach_cnt++; - -if (ue->prach_cnt==3) - ue->generate_prach=0; - -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); -} - #endif void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, @@ -1932,7 +1786,7 @@ if (abstraction_flag == 0) { #endif #if T_TRACER T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]), - T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_nr_PL(ue,eNB_id)),T_INT(nb_rb)); + T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif #ifdef UE_DEBUG_TRACE @@ -2306,7 +2160,7 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_nr_PL(ue,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif #ifdef UE_DEBUG_TRACE @@ -2414,7 +2268,7 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx),T_INT(ue->tx_power_dBm[nr_tti_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_nr_PL(ue,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif #ifdef UE_DEBUG_TRACE LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", @@ -2464,53 +2318,28 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - uint8_t thread_id) + UE_nr_rxtx_proc_t *proc, + uint8_t gNB_id, + uint8_t thread_id) { - //NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - NR_UE_ULSCH_t *ulsch_ue; - NR_UL_UE_HARQ_t *harq_process_ul_ue; //int32_t ulsch_start=0; int slot_tx = proc->nr_tti_tx; int frame_tx = proc->frame_tx; - int harq_pid, i, TBS; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); - LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); + LOG_I(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); #if UE_TIMING_TRACE start_meas(&ue->phy_proc_tx); #endif - - harq_pid = 0; //temporary implementation - - /* - generate_ue_ulsch_params(ue, - 0, - gNB_id, - harq_pid); - */ - - ulsch_ue = ue->ulsch[thread_id][gNB_id][0]; // cwd_index = 0 - harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid]; - - TBS = nr_compute_tbs( harq_process_ul_ue->mcs, harq_process_ul_ue->nb_rb, ulsch_ue->Nsymb_pusch, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, harq_process_ul_ue->Nl); - -//-----------------------------------------------------// - // to be removed later when MAC is ready - - for (i = 0; i < TBS / 8; i++) - harq_process_ul_ue->a[i] = (unsigned char) rand(); - -//-----------------------------------------------------// + uint8_t harq_pid = 0; //temporary implementation nr_ue_ulsch_procedures(ue, harq_pid, slot_tx, - 0, + thread_id, gNB_id); @@ -2525,11 +2354,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, nr_ue_pusch_common_procedures(ue, + harq_pid, slot_tx, - harq_process_ul_ue->Nl, + thread_id, + gNB_id, &ue->frame_parms); + /* if ((ue->UE_mode[eNB_id] == PRACH) && (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) { @@ -2546,7 +2378,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } */ - LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); + LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE @@ -2556,6 +2388,136 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) { + + int frame_tx = proc->frame_tx; + int nr_tti_tx = proc->nr_tti_tx; + int prach_power; + uint16_t preamble_tx=50; + PRACH_RESOURCES_t prach_resources; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); + + ue->generate_nr_prach=0; + if (ue->mac_enabled==0){ + ue->prach_resources[eNB_id] = &prach_resources; + ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx; + ue->prach_resources[eNB_id]->ra_TDD_map_index = 0; + } + + if (ue->mac_enabled==1){ + + // ask L2 for RACH transport + if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { + LOG_D(PHY,"Getting PRACH resources\n"); + //ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,ue->CC_id,frame_tx,eNB_id,nr_tti_tx); + // LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); + // LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]); + } +} + +if (ue->prach_resources[eNB_id]!=NULL) { + + ue->generate_nr_prach=1; + ue->prach_cnt=0; +#ifdef SMBV +ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx; +#endif + +#ifdef OAI_EMU + ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex; +#endif + + if (abstraction_flag == 0) { + + LOG_I(PHY,"mode %d\n",mode); + + if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) { + + ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id); + } + else { + ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm; + ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx; + } + + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", + ue->Mod_id, + frame_tx, + nr_tti_tx, + ue->prach_resources[eNB_id]->ra_PreambleIndex, + get_nr_PL(ue,eNB_id), + ue->tx_power_dBm[nr_tti_tx], + ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, + ue->prach_resources[eNB_id]->ra_TDD_map_index, + ue->prach_resources[eNB_id]->ra_RNTI); + + ue->tx_total_RE[nr_tti_tx] = 96; + +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) + ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + 6); +#else + ue->prach_vars[eNB_id]->amp = AMP; +#endif + if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) + LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n", + ue->Mod_id, + proc->frame_rx, + proc->nr_tti_tx, + ue->tx_power_dBm[nr_tti_tx], + ue->prach_vars[eNB_id]->amp); + + + // start_meas(&ue->tx_prach); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); + +// prach_power = generate_nr_prach(ue,eNB_id,nr_tti_tx,frame_tx); +prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); + // stop_meas(&ue->tx_prach); + LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", + ue->Mod_id, + get_nr_PL(ue,eNB_id), + ue->tx_power_dBm[nr_tti_tx], + dB_fixed(prach_power), + ue->prach_vars[eNB_id]->amp); + }/* else { + UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1; + UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex; + }*/ // commented for compiling as abstraction flag is 0 + + if (ue->mac_enabled==1){ + //mac_xface->Msg1_transmitted(ue->Mod_id,ue->CC_id,frame_tx,eNB_id); + } + +LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", + ue->Mod_id,frame_tx,nr_tti_tx,eNB_id, + ue->prach_resources[eNB_id]->ra_PreambleIndex, + ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id), + get_nr_PL(ue,eNB_id)); + +} + + +// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue +if (mode == calib_prach_tx) + ue->prach_resources[eNB_id]=NULL; + +LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", + ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt); + +ue->prach_cnt++; + +if (ue->prach_cnt==3) + ue->generate_nr_prach=0; + +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); +} + /* void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type) { @@ -2598,14 +2560,14 @@ void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0 if (l==2) { // UE measurements on symbol 0 LOG_D(PHY,"Calling measurements nr_tti_rx %d, rxdata %p\n",nr_tti_rx,ue->common_vars.rxdata); - /* +/* nr_ue_measurements(ue, 0, 0, 0, 0, nr_tti_rx); - */ +*/ //(nr_tti_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) #if T_TRACER @@ -2721,9 +2683,9 @@ void restart_phy(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc, uint8_t eNB_id,uint #endif //(0) void nr_ue_pbch_procedures(uint8_t eNB_id, - PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - uint8_t ssb_index) + PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t abstraction_flag) { // int i; //int pbch_tx_ant=0; @@ -2745,7 +2707,7 @@ void nr_ue_pbch_procedures(uint8_t eNB_id, ue->pbch_vars[eNB_id], &ue->frame_parms, eNB_id, - ssb_index, + ue->nrUE_config.pbch_config.ssb_index, SISO, ue->high_speed_flag); @@ -2826,10 +2788,15 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb #ifdef NR_PDCCH_SCHED -int nr_ue_pdcch_procedures(uint8_t eNB_id, - PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc) +int nr_ue_pdcch_procedures(uint8_t gNB_id, + PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc) { + int frame_rx = proc->frame_rx; + int nr_tti_rx = proc->nr_tti_rx; + unsigned int dci_cnt=0; + + /* // unsigned int dci_cnt=0, i; //removed for nr_ue_pdcch_procedures and added in the loop for nb_coreset_active #ifdef NR_PDCCH_SCHED_DEBUG printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_ue_pdcch_procedures() \n"); @@ -2838,10 +2805,10 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, int frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; NR_DCI_ALLOC_t dci_alloc_rx[8]; - /* - uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1); - uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); - */ + + //uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1); + //uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); + // table dci_fields_sizes_cnt contains dci_fields_sizes for each time a dci is decoded in the slot // each element represents the size in bits for each dci field, for each decoded dci -> [dci_cnt-1] @@ -2894,22 +2861,22 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, for (nb_searchspace_active=0; nb_searchspace_activesearchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset; - if (sl_period_offset_mon == nr_sl1) { - do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every slot - } else if (nr_tti_rx%(uint16_t)sl_period_offset_mon == pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset_offset) { - do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every monitoringSlotPeriodicityAndOffset slot with offset - }*/ - /* - * FIXME - * For PDCCH monitoring when overlap with SS/PBCH according to 38.213 v15.1.0 Section 10 - * To be implemented LATER !!! - */ + //NR_UE_SLOT_PERIOD_OFFSET_t sl_period_offset_mon = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset; + //if (sl_period_offset_mon == nr_sl1) { + //do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every slot + //} else if (nr_tti_rx%(uint16_t)sl_period_offset_mon == pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSlotPeriodicityAndOffset_offset) { + //do_pdcch_monitoring_current_slot=1; // PDCCH monitoring in every monitoringSlotPeriodicityAndOffset slot with offset + //} + + // FIXME + // For PDCCH monitoring when overlap with SS/PBCH according to 38.213 v15.1.0 Section 10 + // To be implemented LATER !!! + //int _offset,_index,_M; //int searchSpace_id = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceId; @@ -2929,11 +2896,11 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, // at the moment we will not take into consideration this variable and we will consider that the OFDM symbol offset is always the first OFDM in a symbol uint16_t symbol_within_slot_mon = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSymbolWithinSlot; // get the remaining parameters describing the current SEARCHSPACE: // FIXME! To be defined where we get this information from - /*NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L1 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel1; - NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L2 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel2; - NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L4 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel4; - NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L8 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel8; - NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L16 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel16;*/ + //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L1 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel1; + //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L2 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel2; + //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L4 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel4; + //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L8 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel8; + //NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L16 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel16; // FIXME! A table of five enum elements // searchSpaceType indicates whether this is a common search space or a UE-specific search space //int searchSpaceType = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceType.type; @@ -2943,27 +2910,27 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, searchSpaceType); #endif - /*while ((searchSpace_coreset_id != pdcch_vars2->coreset[nb_coreset_active].controlResourceSetId) && (nb_coreset_activecoreset[nb_coreset_active].controlResourceSetId) && (nb_coreset_active= nb_coreset_total) return 0; // the coreset_id could not be found. There is a problem - }*/ + } - /* - * we do not need these parameters yet - * + + //we do not need these parameters yet + // get the parameters describing the current CORESET - int coreset_duration = pdcch_vars2->coreset[nb_coreset_active].duration; - uint64_t coreset_freq_dom = pdcch_vars2->coreset[nb_coreset_active].frequencyDomainResources; - int coreset_shift_index = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.shiftIndex; - NR_UE_CORESET_REG_bundlesize_t coreset_bundlesize = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.reg_bundlesize; - NR_UE_CORESET_interleaversize_t coreset_interleaversize = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.interleaversize; - NR_UE_CORESET_precoder_granularity_t precoder_granularity = pdcch_vars2->coreset[nb_coreset_active].precoderGranularity; - int tci_statesPDCCH = pdcch_vars2->coreset[nb_coreset_active].tciStatesPDCCH; - int tci_present = pdcch_vars2->coreset[nb_coreset_active].tciPresentInDCI; - uint16_t pdcch_DMRS_scrambling_id = pdcch_vars2->coreset[nb_coreset_active].pdcchDMRSScramblingID; - */ + //int coreset_duration = pdcch_vars2->coreset[nb_coreset_active].duration; + //uint64_t coreset_freq_dom = pdcch_vars2->coreset[nb_coreset_active].frequencyDomainResources; + //int coreset_shift_index = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.shiftIndex; + // NR_UE_CORESET_REG_bundlesize_t coreset_bundlesize = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.reg_bundlesize; + // NR_UE_CORESET_interleaversize_t coreset_interleaversize = pdcch_vars2->coreset[nb_coreset_active].cce_reg_mappingType.interleaversize; + // NR_UE_CORESET_precoder_granularity_t precoder_granularity = pdcch_vars2->coreset[nb_coreset_active].precoderGranularity; + // int tci_statesPDCCH = pdcch_vars2->coreset[nb_coreset_active].tciStatesPDCCH; + // int tci_present = pdcch_vars2->coreset[nb_coreset_active].tciPresentInDCI; + // uint16_t pdcch_DMRS_scrambling_id = pdcch_vars2->coreset[nb_coreset_active].pdcchDMRSScramblingID; + // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces. // Searchspace types: @@ -3010,108 +2977,53 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, searchSpaceType); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN); + */ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN); + nr_rx_pdcch(ue, + proc->frame_rx, + nr_tti_rx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT); + - crc_scrambled_t crc_scrambled; - format_found_t format_found=255; - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN); #ifdef NR_PDCCH_SCHED_DEBUG - printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure with eNB_id=%d (n_RB_ULBWP=%d, n_RB_DLBWP=%d, searchSpaceType=%d, nb_searchspace_active=%d, nb_coreset_active=%d)\n", - eNB_id, - pdcch_vars2->n_RB_BWP[nb_searchspace_active], - pdcch_vars2->n_RB_BWP[nb_searchspace_active], - searchSpaceType, - nb_searchspace_active, - nb_coreset_active); - + printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure with (nb_searchspace_active=%d)\n", + pdcch_vars->nb_search_space); #endif - dci_cnt += nr_dci_decoding_procedure(nb_searchspace_active, - nb_coreset_active, - ue, - &dci_alloc_rx[dci_cnt], - searchSpaceType, // if we're in PUSCH don't listen to common search space, - // later when we need paging or RA during connection, update this ... - eNB_id, - nr_tti_rx, - dci_fields_sizes_cnt, - pdcch_vars2->n_RB_BWP[nb_searchspace_active], - pdcch_vars2->n_RB_BWP[nb_searchspace_active], - &crc_scrambled, - &format_found, - crc_scrambled_values); + fapi_nr_dci_indication_t dci_ind; + nr_downlink_indication_t dl_indication; + memset((void*)&dci_ind,0,sizeof(dci_ind)); + memset((void*)&dl_indication,0,sizeof(dl_indication)); + dci_cnt = nr_dci_decoding_procedure(ue, + proc->frame_rx, + nr_tti_rx, + &dci_ind); + #ifdef NR_PDCCH_SCHED_DEBUG - printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%d\n",dci_cnt); + LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt); #endif + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT); + //LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT); - //LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx); + for (int i=0; i rnti %x : format %d\n", + ue->Mod_id,frame_rx%1024,nr_tti_rx,mode_string[ue->UE_mode[0]], + i, + dci_ind.dci_list[i].rnti, + dci_ind.dci_list[i].dci_format); + } + ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dci_received += dci_cnt; - /* - uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->nCCE[nr_tti_rx]; - uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[nr_tti_rx]; - uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[nr_tti_rx]; - memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t)); - memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t)); - - LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[nr_tti_rx], next1_thread_id, next2_thread_id); - */ - - LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n", - ue->Mod_id,frame_rx%1024,nr_tti_rx,mode_string[ue->UE_mode[eNB_id]], - dci_cnt, - dci_alloc_rx[0].rnti, - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti, - dci_alloc_rx[0].format ); - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dci_received += dci_cnt; - -#ifdef EMOS - //emos_dump_UE.dci_cnt[nr_tti_rx] = dci_cnt; -#endif dci_ind.number_of_dcis = dci_cnt; - + /* for (int i=0; idlsch_received[eNB_id]++; - - if (dci_alloc_rx[i].rnti == crc_scrambled_values[_SI_RNTI_]) - ue->dlsch_SI_received[eNB_id]++; - if (dci_alloc_rx[i].rnti == crc_scrambled_values[_P_RNTI_]) - ue->dlsch_p_received[eNB_id]++; - if (dci_alloc_rx[i].rnti == crc_scrambled_values[_RA_RNTI_]) - ue->dlsch_ra_received[eNB_id]++; - } - - if ((dci_alloc_rx[i].format == format2_0)){ - } - if ((dci_alloc_rx[i].format == format2_1)){ - } - if ((dci_alloc_rx[i].format == format2_2)){ - } - if ((dci_alloc_rx[i].format == format2_3)){ - } - if ((dci_alloc_rx[i].format == format0_1)){ // This format not implemented at a first time. FIXME - } - if ((dci_alloc_rx[i].format == format1_1)){ // This format not implemented at a first time. FIXME - } - - uint8_t status=0; - - LOG_D(PHY,"<-NR_PDCCH_PHY_PROCEDURES_UE (nr_ue_pdcch_procedures)-> dci_format=%d, rnti=%d, dci_length=%d, dci_pdu[0]=0x%lx, dci_pdu[1]=0x%lx\n",dci_alloc_rx[i].format,dci_alloc_rx[i].rnti,dci_alloc_rx[i].dci_length,dci_alloc_rx[i].dci_pdu[0],dci_alloc_rx[i].dci_pdu[1]); - memset(&dci_ind.dci_list[i].dci,0,sizeof(fapi_nr_dci_pdu_rel15_t)); dci_ind.dci_list[i].rnti = dci_alloc_rx[i].rnti; @@ -3140,36 +3052,15 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, LOG_D(PHY,"<-NR_PDCCH_PHY_PROCEDURES_UE (nr_ue_pdcch_procedures)-> Ending function nr_extract_dci_info()\n"); - /* - nr_generate_ue_ul_dlsch_params_from_dci(ue, - eNB_id, - frame_rx, - nr_tti_rx, - dci_alloc_rx[i].dci_pdu, - dci_alloc_rx[i].rnti, - dci_alloc_rx[i].dci_length, - dci_alloc_rx[i].format, - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id], - ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id], - ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id], - ue->ulsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0], - &ue->frame_parms, - ue->pdsch_config_dedicated, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], - dci_fields_sizes_cnt[i], - pdcch_vars2->n_RB_BWP[nb_searchspace_active], - pdcch_vars2->n_RB_BWP[nb_searchspace_active], - crc_scrambled_values, - &nr_dci_info_extracted); - */ } // end for loop dci_cnt + */ // fill dl_indication message dl_indication.module_id = ue->Mod_id; dl_indication.cc_id = ue->CC_id; - dl_indication.gNB_index = eNB_id; + dl_indication.gNB_index = gNB_id; dl_indication.frame = frame_rx; dl_indication.slot = nr_tti_rx; dl_indication.rx_ind = NULL; //no data, only dci for now @@ -3181,10 +3072,11 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id, #if UE_TIMING_TRACE stop_meas(&ue->dlsch_rx_pdcch_stats); #endif + + + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT); - - - } // end for loop nb_searchspace_active return(dci_cnt); } #endif // NR_PDCCH_SCHED @@ -3329,7 +3221,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t harq_processes_dest->B = current_harq_processes->B ; harq_processes_dest->C = current_harq_processes->C ; - harq_processes_dest->DCINdi = current_harq_processes->DCINdi ; + harq_processes_dest->DCINdi = current_harq_processes->DCINdi ; harq_processes_dest->F = current_harq_processes->F ; harq_processes_dest->G = current_harq_processes->G ; harq_processes_dest->K = current_harq_processes->K ; @@ -3342,6 +3234,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t harq_processes_dest->dl_power_off = current_harq_processes->dl_power_off ; harq_processes_dest->first_tx = current_harq_processes->first_tx ; harq_processes_dest->mcs = current_harq_processes->mcs ; + harq_processes_dest->mcs_table = current_harq_processes->mcs_table ; harq_processes_dest->mimo_mode = current_harq_processes->mimo_mode ; harq_processes_dest->nb_rb = current_harq_processes->nb_rb ; harq_processes_dest->pmi_alloc = current_harq_processes->pmi_alloc ; @@ -3377,25 +3270,31 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB if (dlsch0 && (!dlsch1)) { int harq_pid = dlsch0->current_harq_pid; + uint16_t BWPStart = dlsch0->harq_processes[harq_pid]->BWPStart; + uint16_t BWPSize = dlsch0->harq_processes[harq_pid]->BWPSize; uint16_t pdsch_start_rb = dlsch0->harq_processes[harq_pid]->start_rb; uint16_t pdsch_nb_rb = dlsch0->harq_processes[harq_pid]->nb_rb; uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol; uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols; - LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1); + LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); - for (m = s0; m < (s1 + s0); m++) { - - if (m==s0) + // do channel estimation for first DMRS only + for (m = s0; m < 3; m++) { + if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) > 0) { nr_pdsch_channel_estimation(ue, 0 /*eNB_id*/, nr_tti_rx, 0 /*p*/, m, - ue->frame_parms.first_carrier_offset+pdsch_start_rb*12, + ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12, pdsch_nb_rb); - - + LOG_D(PHY,"Channel Estimation in symbol %d\n",m); + break; + } + } + for (m = s0; m < (s1 + s0); m++) { + dual_stream_UE = 0; eNB_id_i = eNB_id+1; i_mod = 0; @@ -3406,7 +3305,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB first_symbol_flag = 0; #if UE_TIMING_TRACE uint8_t slot = 0; - if(m >= ue->frame_parms.symbols_per_tti>>1) + if(m >= ue->frame_parms.symbols_per_slot>>1) slot = 1; start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]); #endif @@ -3537,13 +3436,13 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod #endif void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - int eNB_id, - PDSCH_t pdsch, - NR_UE_DLSCH_t *dlsch0, - NR_UE_DLSCH_t *dlsch1, - int *dlsch_errors, - runmode_t mode) { + UE_nr_rxtx_proc_t *proc, + int eNB_id, + PDSCH_t pdsch, + NR_UE_DLSCH_t *dlsch0, + NR_UE_DLSCH_t *dlsch1, + int *dlsch_errors, + runmode_t mode) { int harq_pid; int frame_rx = proc->frame_rx; @@ -3553,26 +3452,23 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_UE_PDSCH *pdsch_vars; uint8_t is_cw0_active = 0; uint8_t is_cw1_active = 0; + //nfapi_nr_config_request_t *cfg = &ue->nrUE_config; + //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; + uint8_t nb_re_dmrs = 6; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; + uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value; + uint16_t nb_symb_sch = 9; + nr_downlink_indication_t dl_indication; + fapi_nr_rx_indication_t rx_ind; if (dlsch0==NULL) AssertFatal(0,"dlsch0 should be defined at this level \n"); + harq_pid = dlsch0->current_harq_pid; is_cw0_active = dlsch0->harq_processes[harq_pid]->status; - uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; + nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; + - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dl_config_pdu = &dlsch0->harq_processes[harq_pid]->dl_config_pdu; - uint8_t dmrs_Type = dl_config_pdu->dmrs_Type; - AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type); - uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; - uint8_t dmrs_TypeA_Position = dl_config_pdu->dmrs_TypeA_Position; - AssertFatal(dmrs_TypeA_Position == 2 || dmrs_TypeA_Position == 3,"Illegal dmrs_TypeA_Position %d\n",dmrs_TypeA_Position); - uint16_t dmrs_maxLength = dl_config_pdu->dmrs_maxLength; - AssertFatal(dmrs_maxLength == 1 || dmrs_maxLength == 2,"Illegal dmrs_maxLength %d\n",dmrs_maxLength); - uint16_t dmrs_AdditionalPosition = dl_config_pdu->dmrs_AdditionalPosition; - AssertFatal(dmrs_AdditionalPosition >= 0 && dmrs_AdditionalPosition <= 4,"Illegal dmrs_additional_symbols %d\n",dmrs_AdditionalPosition); - // uint16_t nb_symb_sch = dl_config_pdu->nb_symbols; - // AssertFatal(nb_symb_sch >= 1 && nb_symb_sch <= 14,"Illegal nb_symb_sch %d\n",nb_symb_sch); if(dlsch1) is_cw1_active = dlsch1->harq_processes[harq_pid]->status; @@ -3633,17 +3529,17 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dlsch0->harq_processes[harq_pid]->G = nr_get_G(dlsch0->harq_processes[harq_pid]->nb_rb, nb_symb_sch, nb_re_dmrs, - dmrs_maxLength, + length_dmrs, dlsch0->harq_processes[harq_pid]->Qm, dlsch0->harq_processes[harq_pid]->Nl); #if UE_TIMING_TRACE start_meas(&ue->dlsch_unscrambling_stats); #endif nr_dlsch_unscrambling(pdsch_vars->llr[0], - dlsch0->harq_processes[harq_pid]->G, - 0, - ue->frame_parms.Nid_cell, - dlsch0->rnti); + dlsch0->harq_processes[harq_pid]->G, + 0, + ue->frame_parms.Nid_cell, + dlsch0->rnti); #if UE_TIMING_TRACE @@ -3717,7 +3613,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb, nb_symb_sch, nb_re_dmrs, - dmrs_maxLength, + length_dmrs, dlsch1->harq_processes[harq_pid]->Qm, dlsch1->harq_processes[harq_pid]->Nl); #if UE_TIMING_TRACE @@ -3797,6 +3693,33 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_tti_rx); + + LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d, TBS expected dlsch1: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS, dlsch1->harq_processes[harq_pid]->TBS); + + if(retmax_ldpc_iterations+1){ + // fill dl_indication message + dl_indication.module_id = ue->Mod_id; + dl_indication.cc_id = ue->CC_id; + dl_indication.gNB_index = eNB_id; + dl_indication.frame = frame_rx; + dl_indication.slot = nr_tti_rx; + + dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance + dl_indication.proc=proc; + + //dl_indication.rx_ind->number_pdus + rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH; + rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b; + rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3; + LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length); + rx_ind.number_pdus = 1; + + //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now + dl_indication.dci_ind = NULL; //&ue->dci_ind; + // send to mac + if (ue->if_inst && ue->if_inst->dl_indication) + ue->if_inst->dl_indication(&dl_indication); + } } @@ -3907,7 +3830,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { 0); */ // 1- perform FFT - for (int l=1; lframe_parms.symbols_per_tti>>1; l++) + for (int l=1; lframe_parms.symbols_per_slot>>1; l++) { //if( (l != pilot0) && (l != pilot1)) { @@ -3939,7 +3862,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { } // 2- perform Channel Estimation for slot1 - for (int l=1; lframe_parms.symbols_per_tti>>1; l++) + for (int l=1; lframe_parms.symbols_per_slot>>1; l++) { if(l == pilot1) { @@ -3967,9 +3890,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) { - // fix this for multi-threaded case - uint8_t ssb_index=0; - ue_pbch_procedures(0,ue,proc,0,ssb_index); + ue_pbch_procedures(0,ue,proc,0); } proc->chan_est_slot1_available = 1; @@ -4029,8 +3950,8 @@ void *UE_thread_slot1_dl_processing(void *arg) { PDSCH, ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0], NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, + (ue->frame_parms.symbols_per_slot>>1), + ue->frame_parms.symbols_per_slot-1, abstraction_flag); LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx); @@ -4044,8 +3965,8 @@ void *UE_thread_slot1_dl_processing(void *arg) { SI_PDSCH, ue->dlsch_SI[eNB_id], NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, + (ue->frame_parms.symbols_per_slot>>1), + ue->frame_parms.symbols_per_slot-1, abstraction_flag); } @@ -4057,8 +3978,8 @@ void *UE_thread_slot1_dl_processing(void *arg) { P_PDSCH, ue->dlsch_p[eNB_id], NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, + (ue->frame_parms.symbols_per_slot>>1), + ue->frame_parms.symbols_per_slot-1, abstraction_flag); } // do procedures for RA-RNTI @@ -4069,8 +3990,8 @@ void *UE_thread_slot1_dl_processing(void *arg) { RA_PDSCH, ue->dlsch_ra[eNB_id], NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, + (ue->frame_parms.symbols_per_slot>>1), + ue->frame_parms.symbols_per_slot-1, abstraction_flag); } @@ -4104,53 +4025,46 @@ void *UE_thread_slot1_dl_processing(void *arg) { #endif +int is_pbch_in_slot(fapi_nr_pbch_config_t *pbch_config, int frame, int slot, int periodicity, uint16_t slots_per_frame) { -fapi_nr_dl_config_bch_pdu *is_pbch_in_slot(fapi_nr_dl_config_request_t *DLconfigreq, int frame, int slot, int periodicity, uint16_t slots_per_frame) { + int ssb_slot_decoded = (pbch_config->ssb_index)/2; - for (int i=0;inumber_pdus;i++) { - - if (DLconfigreq->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_BCH_PDU_TYPE) { - int ssb_slot_decoded = (DLconfigreq->dl_config_list[i].bch_config_pdu.ssb_index)/2; - // All this checking should be done MAC - if (periodicity == 5) { - // check for pbch in corresponding slot each half frame - if (DLconfigreq->dl_config_list[i].bch_config_pdu.half_frame_bit) { - if (slot == ssb_slot_decoded || slot == ssb_slot_decoded - slots_per_frame/2) return(&DLconfigreq->dl_config_list[i].bch_config_pdu); - } - else { - if (slot == ssb_slot_decoded || slot == ssb_slot_decoded + slots_per_frame/2) return(&DLconfigreq->dl_config_list[i].bch_config_pdu); - } - } - else { - // if the current frame is supposed to contain ssb - if (!((frame-(DLconfigreq->dl_config_list[i].bch_config_pdu.system_frame_number))%(periodicity/10))) { - if (slot == ssb_slot_decoded) return(&DLconfigreq->dl_config_list[i].bch_config_pdu); - } - } - } + if (periodicity == 5) { + // check for pbch in corresponding slot each half frame + if (pbch_config->half_frame_bit) + return(slot == ssb_slot_decoded || slot == ssb_slot_decoded - slots_per_frame/2); + else + return(slot == ssb_slot_decoded || slot == ssb_slot_decoded + slots_per_frame/2); + } + else { + // if the current frame is supposed to contain ssb + if (!((frame-(pbch_config->system_frame_number))%(periodicity/10))) + return(slot == ssb_slot_decoded); + else + return 0; } - return NULL; } - -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, - fapi_nr_dl_config_request_t *DLconfigreq) { - - - +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 frame_rx = proc->frame_rx; int nr_tti_rx = proc->nr_tti_rx; + int slot_pbch; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; NR_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; uint8_t harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid; NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; uint16_t nb_symb_sch = dlsch0_harq->nb_symbols; - uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration; + uint16_t start_symb_sch = dlsch0_harq->start_symbol; + uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0; uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) uint8_t dci_cnt = 0; - + fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); @@ -4159,20 +4073,48 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); */ - uint8_t coreset_start=0, coreset_start_set=0; - uint16_t coreset_count = 0; - uint64_t coreset_freq_dom = pdcch_vars->coreset[0].frequencyDomainResources; - for (int i = 0; i < 45; i++) { - if (((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (44-i)) & 0x1) { - if (!coreset_start_set) { - coreset_start = i; - coreset_start_set = 1; + + int coreset_nb_rb=0; + int coreset_start_rb=0; + if (pdcch_vars->nb_search_space > 0) + get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb); + + slot_pbch = is_pbch_in_slot(pbch_config, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame); + + // looking for pbch only in slot where it is supposed to be + if ((ue->decode_MIB == 1) && slot_pbch) + { + LOG_I(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + + for (int i=1; i<4; i++) { + + nr_slot_fep(ue, + (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot), + nr_tti_rx, + 0, + 0); + +#if UE_TIMING_TRACE + start_meas(&ue->dlsch_channel_estimation_stats); +#endif + nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(pbch_config->ssb_index)&7,pbch_config->half_frame_bit); +#if UE_TIMING_TRACE + stop_meas(&ue->dlsch_channel_estimation_stats); +#endif + + } + nr_ue_pbch_procedures(eNB_id,ue,proc,0); + + if (ue->no_timing_correction==0) { + LOG_I(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction); + nr_adjust_synch_ue(&ue->frame_parms, + ue, + eNB_id, + nr_tti_rx, + 0, + 16384); } - coreset_count++; } - } - uint16_t coreset_nb_rb = 6 * coreset_count; - uint16_t coreset_start_rb = 6 * coreset_start; #ifdef NR_PDCCH_SCHED nr_gold_pdcch(ue, 0, 2); @@ -4190,12 +4132,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN 0, 0); - nr_pdcch_channel_estimation(ue, - 0, - nr_tti_rx, - l, - ue->frame_parms.first_carrier_offset+coreset_start_rb*12, - coreset_nb_rb); + // note: this only works if RBs for PDCCH are contigous! + LOG_D(PHY,"pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d\n", + ue->frame_parms.first_carrier_offset,pdcch_vars->pdcch_config[0].BWPStart,coreset_start_rb); + if (coreset_nb_rb > 0) + nr_pdcch_channel_estimation(ue, + 0, + nr_tti_rx, + l, + ue->frame_parms.first_carrier_offset+(pdcch_vars->pdcch_config[0].BWPStart + coreset_start_rb)*12, + coreset_nb_rb); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE @@ -4211,17 +4157,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN if (dci_cnt > 0) { - LOG_I(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_cnt); - - if (ue->no_timing_correction==0) { - LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction); - nr_adjust_synch_ue(&ue->frame_parms, - ue, - eNB_id, - nr_tti_rx, - 0, - 16384); - } + LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_cnt); + } else { LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n",ue->Mod_id,frame_rx,nr_tti_rx); } @@ -4231,11 +4168,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN if (dci_cnt > 0){ LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); //to update from pdsch config - nr_gold_pdsch(ue,nb_symb_pdcch,0, 1); + start_symb_sch = dlsch0_harq->start_symbol; + int symb_dmrs=-1; + for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;} + AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n"); + LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos); + nr_gold_pdsch(ue,symb_dmrs,0, 1); nb_symb_sch = dlsch0_harq->nb_symbols; - for (uint16_t m=nb_symb_pdcch;m<=(nb_symb_sch+nb_symb_pdcch-1) ; m++){ + for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ nr_slot_fep(ue, m, //to be updated from higher layer nr_tti_rx, @@ -4247,7 +4189,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN //set active for testing, to be removed ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 1; } - else + else ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0; #if UE_TIMING_TRACE @@ -4316,37 +4258,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } - - fapi_nr_dl_config_bch_pdu *bch_config = is_pbch_in_slot(DLconfigreq, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame); - - // looking for pbch only in slot where it is supposed to be - if ((ue->decode_MIB == 1) && bch_config) - { - LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - - for (int i=1; i<4; i++) { - - nr_slot_fep(ue, - (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot), - nr_tti_rx, - 0, - 0); - -#if UE_TIMING_TRACE - start_meas(&ue->dlsch_channel_estimation_stats); -#endif - nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(bch_config->ssb_index)&7,bch_config->half_frame_bit); -#if UE_TIMING_TRACE - stop_meas(&ue->dlsch_channel_estimation_stats); -#endif - - } - nr_ue_pbch_procedures(eNB_id,ue,proc,bch_config->ssb_index); - } - + // do procedures for C-RNTI if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { + LOG_D(PHY, "DLSCH data reception at nr_tti_rx: %d \n \n", nr_tti_rx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); #if UE_TIMING_TRACE @@ -4580,192 +4496,3 @@ uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue, return(0); } -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) { - - int frame_tx = proc->frame_tx; - int nr_tti_tx = proc->nr_tti_tx; - int prach_power; - uint16_t preamble_tx=50; - PRACH_RESOURCES_t prach_resources; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); - - ue->generate_nr_prach=0; - if (ue->mac_enabled==0){ - ue->prach_resources[eNB_id] = &prach_resources; - ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx; - ue->prach_resources[eNB_id]->ra_TDD_map_index = 0; - } - - if (ue->mac_enabled==1){ - - // ask L2 for RACH transport - if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { - LOG_D(PHY,"Getting PRACH resources\n"); - //ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,ue->CC_id,frame_tx,eNB_id,nr_tti_tx); - // LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); - // LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]); - } -} - -if (ue->prach_resources[eNB_id]!=NULL) { - - ue->generate_nr_prach=1; - ue->prach_cnt=0; -#ifdef SMBV -ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx; -#endif - -#ifdef OAI_EMU - ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex; -#endif - - if (abstraction_flag == 0) { - - LOG_I(PHY,"mode %d\n",mode); - - if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) { - - ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id); - } - else { - ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm; - ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx; - } - - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", - ue->Mod_id, - frame_tx, - nr_tti_tx, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - get_nr_PL(ue,eNB_id), - ue->tx_power_dBm[nr_tti_tx], - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, - ue->prach_resources[eNB_id]->ra_TDD_map_index, - ue->prach_resources[eNB_id]->ra_RNTI); - - ue->tx_total_RE[nr_tti_tx] = 96; - -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 6); -#else - ue->prach_vars[eNB_id]->amp = AMP; -#endif - if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) - LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n", - ue->Mod_id, - proc->frame_rx, - proc->nr_tti_tx, - ue->tx_power_dBm[nr_tti_tx], - ue->prach_vars[eNB_id]->amp); - - - // start_meas(&ue->tx_prach); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); - -// prach_power = generate_nr_prach(ue,eNB_id,nr_tti_tx,frame_tx); -prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); - // stop_meas(&ue->tx_prach); - LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", - ue->Mod_id, - get_nr_PL(ue,eNB_id), - ue->tx_power_dBm[nr_tti_tx], - dB_fixed(prach_power), - ue->prach_vars[eNB_id]->amp); - }/* else { - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1; - UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex; - }*/ // commented for compiling as abstraction flag is 0 - - if (ue->mac_enabled==1){ - //mac_xface->Msg1_transmitted(ue->Mod_id,ue->CC_id,frame_tx,eNB_id); - } - -LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", - ue->Mod_id,frame_tx,nr_tti_tx,eNB_id, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id), - get_nr_PL(ue,eNB_id)); - -} - - -// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue -if (mode == calib_prach_tx) - ue->prach_resources[eNB_id]=NULL; - -LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", - ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt); - -ue->prach_cnt++; - -if (ue->prach_cnt==3) - ue->generate_nr_prach=0; - -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); -} - - -//Yet to be done -/* void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type) { - - NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - int32_t ulsch_start=0; - int nr_tti_tx = proc->nr_tti_tx; - int frame_tx = proc->frame_tx; - unsigned int aa; - uint8_t isSubframeSRS; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); - - LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, nr_tti_tx); - ue->generate_ul_signal[eNB_id] = 0; - - -#if UE_TIMING_TRACE - start_meas(&ue->phy_proc_tx); -#endif - - ue->tx_power_dBm[nr_tti_tx]=-127; -printf("ue mode =%d\n",ue->UE_mode[eNB_id]); - - if (abstraction_flag==0) { - for (aa=0; aanb_antennas_tx; aa++) { - memset(&ue->common_vars.txdataF[aa][nr_tti_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],0,frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t)); - } - } - -if (abstraction_flag == 0) { - ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0)); - } - -ue->UE_mode[eNB_id]=1; -ue->frame_parms.prach_config_common.prach_Config_enabled=1; -printf("S: ue->UE_mode[eNB_id] == PRACH is %d and ue->frame_parms.prach_config_common.prach_Config_enabled is %d\n", ue->UE_mode[eNB_id],ue->frame_parms.prach_config_common.prach_Config_enabled); - if ((ue->UE_mode[eNB_id] == PRACH) && - (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) { - - // check if we have PRACH opportunity - if (is_nr_prach_subframe(&ue->frame_parms,frame_tx,nr_tti_tx)) { -printf("the value of is_nr_prach subframe is %d\n",is_nr_prach_subframe(&ue->frame_parms,frame_tx,nr_tti_tx)); - nr_ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); - } - } // mode is PRACH - else { - ue->generate_prach=0; - } - -LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, nr_tti_tx); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); -#if UE_TIMING_TRACE - stop_meas(&ue->phy_proc_tx); -#endif -} */ - - diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c index d43f4ade05..d955cbb242 100644 --- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c @@ -103,7 +103,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH; - int16_t PL = get_nr_PL(ue,gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ + int16_t PL = 100;//get_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ int16_t delta_F_PUCCH = power_config->deltaF_PUCCH_f[pucch_format]; @@ -214,3 +214,4 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, return (pucch_power); } + diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 93059c00e0..74a2ea5cbc 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -1,5 +1,4 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under @@ -212,11 +211,11 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ /* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */ sr_payload = nr_ue_get_SR(Mod_id, - CC_id, - frame_tx, - gNB_id, - ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, - nr_tti_tx); // nr_tti_rx used for meas gap + CC_id, + frame_tx, + gNB_id, + 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, + nr_tti_tx); // nr_tti_rx used for meas gap } else { sr_payload = 1; @@ -591,7 +590,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ case pucch_format2_nr: { nr_generate_pucch2(ue, - ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, + 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, &ue->pucch_config_dedicated[gNB_id], @@ -609,7 +608,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ case pucch_format4_nr: { nr_generate_pucch3_4(ue, - ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, + 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, format, @@ -922,7 +921,7 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int uci_size /* a valid resource has already be found outside this function */ resource_set_found = TRUE; ready_pucch_resource_id = TRUE; - pucch_resource_indicator = pucch_resource_indicator; + //pucch_resource_indicator = pucch_resource_indicator; } if (resource_set_found == TRUE) { @@ -1215,3 +1214,4 @@ void set_csi_nr(int csi_status, uint32_t csi_payload) } } + diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index d04403d43c..6706b0f912 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -35,38 +35,30 @@ #include #include #include - -#include "SIMULATION/TOOLS/sim.h" +#include "common/config/config_load_configmodule.h" +#include "common/utils/LOG/log.h" +#include "LAYER2/MAC/mac_vars.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "PHY/types.h" #include "PHY/defs_eNB.h" #include "PHY/defs_UE.h" #include "PHY/phy_vars.h" - -#include "SCHED/sched_eNB.h" -#include "SCHED/sched_common_vars.h" -#include "LAYER2/MAC/mac_vars.h" - -#include "OCG_vars.h" -#include "common/utils/LOG/log.h" -#include "UTIL/LISTS/list.h" - -#include "unitary_defs.h" - - -#include "PHY/TOOLS/lte_phy_scope.h" - -#include "dummy_functions.c" - +#include "PHY/INIT/phy_init.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/MODULATION/modulation_common.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" -#include "PHY/LTE_TRANSPORT/transport_proto.h" -#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/TOOLS/lte_phy_scope.h" #include "SCHED/sched_eNB.h" +#include "SCHED/sched_common_vars.h" #include "SCHED_UE/sched_UE.h" -#include "common/config/config_load_configmodule.h" -#include "PHY/INIT/phy_init.h" -#include "nfapi/oai_integration/vendor_ext.h" +#include "SIMULATION/TOOLS/sim.h" +#include "UTIL/LISTS/list.h" +#include "OCG_vars.h" +#include "unitary_defs.h" +#include "dummy_functions.c" +#include "executables/thread-common.h" void feptx_ofdm(RU_t *ru, int frame, int subframe); void feptx_prec(RU_t *ru, int frame, int subframe); @@ -85,30 +77,6 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ -//THREAD_STRUCT thread_struct; -static THREAD_STRUCT thread_struct; - -void set_parallel_conf(char *parallel_conf) { - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) { - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) { - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) { - return thread_struct.worker_conf; -} - - int emulate_rf = 0; void handler(int sig) { @@ -122,8 +90,6 @@ void handler(int sig) { exit(1); } - - //DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_2A[2]; DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_1E[2]; diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index 2c0385efbf..80598b37e4 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -58,7 +58,7 @@ #define BW 5.0 -PHY_VARS_eNB *PHY_vars_eNB,*PHY_vars_eNB1,*PHY_vars_eNB2; +PHY_VARS_eNB *PHY_vars_eNB, *PHY_vars_eNB1, *PHY_vars_eNB2; PHY_VARS_UE *PHY_vars_UE[2]; #define DLSCH_RB_ALLOC 0x1fff // igore DC component,RB13 @@ -699,7 +699,7 @@ int main(int argc, char **argv) { bzero(txdataF2[0],FRAME_LENGTH_BYTES_NO_PREFIX); bzero(txdataF2[1],FRAME_LENGTH_BYTES_NO_PREFIX); #else - txdata = PHY_vars_eNB->lte_eNB_common_vars.txdata[eNb_id]; + txdata = PHY_vars_eNB->common_vars.txdataF[eNb_id]; txdata1 = PHY_vars_eNB1->lte_eNB_common_vars.txdata[eNb_id]; txdata2 = PHY_vars_eNB2->lte_eNB_common_vars.txdata[eNb_id]; #endif diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index be69e96897..db97240ed5 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -33,30 +33,28 @@ #include #include #include -#include "SIMULATION/TOOLS/sim.h" +#include "LAYER2/MAC/mac_vars.h" #include "PHY/types.h" #include "PHY/defs_common.h" #include "PHY/defs_eNB.h" #include "PHY/defs_UE.h" #include "PHY/phy_vars.h" -#include "targets/RT/USER/lte-softmodem.h" - +#include "PHY/INIT/phy_init.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" +#include "PHY/TOOLS/lte_phy_scope.h" #include "SCHED/sched_common_vars.h" #include "SCHED/sched_eNB.h" #include "SCHED_UE/sched_UE.h" -#include "LAYER2/MAC/mac_vars.h" +#include "SIMULATION/TOOLS/sim.h" #include "OCG_vars.h" - -#include "PHY/LTE_TRANSPORT/transport_proto.h" -#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" -#include "PHY/INIT/phy_init.h" - #include "unitary_defs.h" - -#include "PHY/TOOLS/lte_phy_scope.h" #include "dummy_functions.c" #include "nfapi/oai_integration/vendor_ext.h" #include "common/config/config_load_configmodule.h" +#include "executables/thread-common.h" +#include "targets/RT/USER/lte-softmodem.h" + double cpuf; #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) //#define MCS_COUNT 23//added for PHY abstraction @@ -96,7 +94,6 @@ nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; nfapi_tx_request_t TX_req; Sched_Rsp_t sched_resp; -THREAD_STRUCT thread_struct; void fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index f4956529a8..5667ceb981 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -53,46 +53,12 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + double cpuf; int nfapi_mode = 0; +uint16_t NB_UE_INST = 1; -int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { - return (0); -} -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { - return (0); -} - -int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { - return (0); -} - -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { - return (0); -} - -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { - return (0); -} - -uint32_t from_nrarfcn(int nr_bandP, uint32_t dl_earfcn) { - return (0); -} -int32_t get_nr_uldl_offset(int eutra_bandP) { - return (0); -} - -NR_IF_Module_t * -NR_IF_Module_init(int Mod_id) { - return (NULL); -} - -void exit_function(const char *file, const char *function, const int line, - const char *s) { - const char *msg = s == NULL ? "no comment" : s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); -} // needed for some functions @@ -133,7 +99,6 @@ int main(int argc, char **argv) int frame_length_complex_samples; //int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; - //nfapi_nr_config_request_t *gNB_config; uint8_t Kmimo = 0; uint32_t Nsoft = 0; double sigma; @@ -146,6 +111,7 @@ int main(int argc, char **argv) uint16_t nb_symb_sch = 12; uint16_t nb_rb = 50; uint8_t Imcs = 9; + uint8_t mcs_table = 0; cpuf = get_cpu_freq_GHz(); @@ -457,7 +423,7 @@ int main(int argc, char **argv) UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0); unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0]; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15; //time_stats_t *rm_stats, *te_stats, *i_stats; uint8_t is_crnti = 0, llr8_flag = 0; unsigned int TBS = 8424; @@ -465,6 +431,7 @@ int main(int argc, char **argv) uint8_t nb_re_dmrs = 6; uint16_t length_dmrs = 1; unsigned char mod_order; + uint16_t rate; uint8_t Nl = 1; uint8_t rvidx = 0; dlsch->rnti = 1; @@ -472,16 +439,22 @@ int main(int argc, char **argv) dlsch->harq_processes[0]->rvidx = rvidx;*/ //printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe], // dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl); - mod_order = nr_get_Qm(Imcs, 1); + mod_order = nr_get_Qm_dl(Imcs, mcs_table); + rate = nr_get_code_rate_dl(Imcs, mcs_table); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl); - printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order); + TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl); + printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); //dlsch->harq_ids[subframe]= 0; - rel15->n_prb = nb_rb; - rel15->nb_symbols = nb_symb_sch; - rel15->modulation_order = mod_order; - rel15->nb_layers = Nl; - rel15->transport_block_size = TBS; + rel15->rbSize = nb_rb; + rel15->NrOfSymbols = nb_symb_sch; + rel15->qamModOrder[0] = mod_order; + rel15->nrOfLayers = Nl; + rel15->TBSize[0] = TBS>>3; + rel15->targetCodeRate[0] = rate; + rel15->NrOfCodewords = 1; + rel15->dmrsConfigType = NFAPI_NR_DMRS_TYPE1; + rel15->dlDmrsSymbPos = 4; + rel15->mcsIndex[0] = Imcs; double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384); short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384); @@ -496,10 +469,14 @@ int main(int argc, char **argv) NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0]; NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid]; harq_process->mcs = Imcs; + harq_process->mcs_table = mcs_table; harq_process->Nl = Nl; harq_process->nb_rb = nb_rb; harq_process->Qm = mod_order; harq_process->rvidx = rvidx; + harq_process->R = rate; + harq_process->dmrsConfigType = 1; + harq_process->dlDmrsSymbPos = 4; printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch); unsigned char *test_input; test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8); @@ -510,7 +487,7 @@ int main(int argc, char **argv) //estimated_output = harq_process->b; #ifdef DEBUG_NR_DLSCHSIM - for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]); + for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%hhu \n",test_input[i]); #endif /*for (int i=0; i0x%08x\n",crc24c(test_input, 32)); // generate signal if (input_fd == NULL) { - nr_dlsch_encoding(test_input, frame, slot, dlsch, frame_parms); + nr_dlsch_encoding(test_input, frame, slot, dlsch, frame_parms,NULL,NULL,NULL,NULL,NULL,NULL,NULL); } for (SNR = snr0; SNR < snr1; SNR += snr_step) { @@ -553,9 +530,11 @@ int main(int argc, char **argv) //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]); //channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits); - - //if (i<16) printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]); - +/* + if (i<16) printf("input[%d] %f => channel_output_fixed[%d] = %d\n", + i,modulated_input[i], + i,channel_output_fixed[i]); +*/ //Uncoded BER if (channel_output_fixed[i] < 0) channel_output_uncoded[i] = 1; //QPSK demod @@ -600,7 +579,7 @@ int main(int argc, char **argv) if (errors_bit > 0) { n_false_positive++; if (n_trials == 1) - printf("errors_bit %d (trial %d)\n", errors_bit, trial); + printf("errors_bit %u (trial %d)\n", errors_bit, trial); } } @@ -649,9 +628,9 @@ int main(int argc, char **argv) for (i = 0; i < 2; i++) { printf("gNB %d\n", i); - free_gNB_dlsch(gNB->dlsch[0][i]); + free_gNB_dlsch(gNB->dlsch[0][i],N_RB_DL); printf("UE %d\n", i); - free_nr_ue_dlsch(UE->dlsch[0][0][i]); + free_nr_ue_dlsch(&(UE->dlsch[0][0][i]),N_RB_DL); } for (i = 0; i < 2; i++) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 09f2034d10..056f808be3 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -61,38 +61,30 @@ #include "openair1/SIMULATION/RF/rf.h" #include "openair1/SIMULATION/TOOLS/sim.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" -#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" +//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" + +#include "NR_RRCReconfiguration.h" +#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +#include "SIMULATION/LTE_PHY/common_sim.h" + + PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + double cpuf; int sf_ahead=4; // dummy functions +int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } + +void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} + int nfapi_mode=0; -int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } -int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } - -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } - -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {return(0);} - - - -int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info){return(0);} -int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info){return(0);} - -lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe) { return(SF_DL);} - -void exit_function(const char* file, const char* function, const int line,const char *s) { - const char * msg= s==NULL ? "no comment": s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); -} int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, @@ -105,207 +97,79 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, } +uint16_t NB_UE_INST = 1; + //Dummy Functions -lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms, unsigned char subframe) {return(SF_DL);} -int rlc_module_init (void) {return(0);} +//lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms, unsigned char subframe) {return(SF_DL);} +int rlc_module_init (int eNB_id) {return(0);} + void pdcp_layer_init(void) {} int rrc_init_nr_global_param(void){return(0);} -void config_common(int Mod_idP, +void config_common(int Mod_idP, + int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc ); +uint64_t get_softmodem_optmask(void) {return 0;} +mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id) +{mac_rlc_status_resp_t mac_rlc_status_resp={0}; return mac_rlc_status_resp;} +tbs_size_t mac_rlc_data_req( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + char *buffer_pP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id ) +{return 0;} +int generate_dlsch_header(unsigned char *mac_header, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding){return 0;} +void nr_ip_over_LTE_DRB_preconfiguration(void){} +void mac_rlc_data_ind ( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + char *buffer_pP, + const tb_size_t tb_sizeP, + num_tb_t num_tbP, + crc_t *crcs_pP) +{} + // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; -void prepare_scc_sim(NR_ServingCellConfigCommon_t *scc) { - - NR_FreqBandIndicatorNR_t *dl_frequencyBandList,*ul_frequencyBandList; - struct NR_SCS_SpecificCarrier *dl_scs_SpecificCarrierList,*ul_scs_SpecificCarrierList; - struct NR_PDSCH_TimeDomainResourceAllocation *bwp_dl_timedomainresourceallocation; - struct NR_PUSCH_TimeDomainResourceAllocation *pusch_configcommontimedomainresourceallocation; - // struct NR_RateMatchPattern *ratematchpattern; - // NR_RateMatchPatternId_t *ratematchpatternid; - // NR_TCI_StateId_t *TCI_StateId; - // struct NR_ControlResourceSet *bwp_dl_controlresourceset; - // NR_SearchSpace_t *bwp_dl_searchspace; - - scc->physCellId = CALLOC(1,sizeof(NR_PhysCellId_t)); - scc->downlinkConfigCommon = CALLOC(1,sizeof(struct NR_DownlinkConfigCommon)); - scc->downlinkConfigCommon->frequencyInfoDL = CALLOC(1,sizeof(struct NR_FrequencyInfoDL)); - scc->downlinkConfigCommon->initialDownlinkBWP = CALLOC(1,sizeof(struct NR_BWP_DownlinkCommon)); - scc->uplinkConfigCommon = CALLOC(1,sizeof(struct NR_UplinkConfigCommon)); - scc->uplinkConfigCommon->frequencyInfoUL = CALLOC(1,sizeof(struct NR_FrequencyInfoUL)); - scc->uplinkConfigCommon->initialUplinkBWP = CALLOC(1,sizeof(struct NR_BWP_UplinkCommon)); - //scc->supplementaryUplinkConfig = CALLOC(1,sizeof(struct NR_UplinkConfigCommon)); - scc->ssb_PositionsInBurst = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__ssb_PositionsInBurst)); - scc->ssb_periodicityServingCell = CALLOC(1,sizeof(long)); - // scc->rateMatchPatternToAddModList = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__rateMatchPatternToAddModList)); - // scc->rateMatchPatternToReleaseList = CALLOC(1,sizeof(struct NR_ServingCellConfigCommon__rateMatchPatternToReleaseList)); - scc->subcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); - scc->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); - scc->tdd_UL_DL_ConfigurationCommon->pattern2 = CALLOC(1,sizeof(struct NR_TDD_UL_DL_Pattern)); - - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB = CALLOC(1,sizeof(NR_ARFCN_ValueNR_t)); - - dl_frequencyBandList = CALLOC(1,sizeof(NR_FreqBandIndicatorNR_t)); - dl_scs_SpecificCarrierList = CALLOC(1,sizeof(struct NR_SCS_SpecificCarrier)); - - ASN_SEQUENCE_ADD(&scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list,dl_frequencyBandList); - ASN_SEQUENCE_ADD(&scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list,dl_scs_SpecificCarrierList); - // scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix = CALLOC(1,sizeof(long)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PDCCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero = CALLOC(1,sizeof(long)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero = CALLOC(1,sizeof(long)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = CALLOC(1,sizeof(struct NR_ControlResourceSet)); - - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = CALLOC(1,sizeof(NR_SearchSpaceId_t)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation = CALLOC(1,sizeof(NR_SearchSpaceId_t)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->pagingSearchSpace = CALLOC(1,sizeof(NR_SearchSpaceId_t)); - // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace = CALLOC(1,sizeof(NR_SearchSpaceId_t)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PDSCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->present = NR_SetupRelease_PDSCH_ConfigCommon_PR_setup; - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDSCH_ConfigCommon)); - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList = CALLOC(1,sizeof(struct NR_PDSCH_TimeDomainResourceAllocationList)); - // - for (int i=0;ik0 = CALLOC(1,sizeof(long)); - *bwp_dl_timedomainresourceallocation->k0=0; - ASN_SEQUENCE_ADD(&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list, - bwp_dl_timedomainresourceallocation); - } - - ul_frequencyBandList = CALLOC(1,sizeof(NR_FreqBandIndicatorNR_t)); - scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList = CALLOC(1,sizeof(struct NR_MultiFrequencyBandListNR)); - ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list,ul_frequencyBandList); - - scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = CALLOC(1,sizeof(NR_ARFCN_ValueNR_t)); - // scc->uplinkConfigCommon->frequencyInfoUL->additionalSpectrumEmission = CALLOC(1,sizeof(NR_AdditionalSpectrumEmission_t)); - scc->uplinkConfigCommon->frequencyInfoUL->p_Max = CALLOC(1,sizeof(NR_P_Max_t)); - // scc->uplinkConfigCommon->frequencyInfoUL->frequencyShift7p5khz = CALLOC(1,sizeof(long)); - - // scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.cyclicPrefix = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_RACH_ConfigCommon_t)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon)); - // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB)); - // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->groupBconfigured = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__groupBconfigured)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB = CALLOC(1,sizeof(NR_RSRP_Range_t)); - // scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t)); - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup; - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon)); - - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding = CALLOC(1,sizeof(long)); - - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocationList)); - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant = CALLOC(1,sizeof(long)); - - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon = CALLOC(1,sizeof(struct NR_SetupRelease_PUCCH_ConfigCommon)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUCCH_ConfigCommon)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon = CALLOC(1,sizeof(long)); - scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId = CALLOC(1,sizeof(long)); - - // scc->ssb_PositionsInBurst->choice.shortBitmap.buf = MALLOC(1); - // scc->ssb_PositionsInBurst->choice.mediumBitmap.buf = MALLOC(1); - // scc->ssb_PositionsInBurst->choice.longBitmap.buf = MALLOC(8); - - ul_frequencyBandList = CALLOC(1,sizeof(NR_FreqBandIndicatorNR_t)); - ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list,ul_frequencyBandList); - - ul_scs_SpecificCarrierList = CALLOC(1,sizeof(struct NR_SCS_SpecificCarrier)); - ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list,ul_scs_SpecificCarrierList); - - for (int i=0;ik2 = CALLOC(1,sizeof(long)); - *pusch_configcommontimedomainresourceallocation->k2=0; - ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_configcommontimedomainresourceallocation); - } - //ratematchpattern = CALLOC(1,sizeof(struct NR_RateMatchPattern)); - //ratematchpattern->patternType.choice.bitmaps = CALLOC(1,sizeof(struct NR_RateMatchPattern__patternType__bitmaps)); - //ratematchpattern->patternType.choice.bitmaps->resourceBlocks.buf = MALLOC(35); - //ratematchpattern->patternType.choice.bitmaps->symbolsInResourceBlock.choice.oneSlot.buf = MALLOC(2); - //ratematchpattern->patternType.choice.bitmaps->symbolsInResourceBlock.choice.twoSlots.buf = MALLOC(4); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern = CALLOC(1,sizeof(struct NR_RateMatchPattern__patternType__bitmaps__periodicityAndPattern)); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n2.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n4.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n5.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n8.buf = MALLOC(1); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n10.buf = MALLOC(2); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n20.buf = MALLOC(3); - //ratematchpattern->patternType.choice.bitmaps->periodicityAndPattern->choice.n40.buf = MALLOC(5); - //ratematchpattern->subcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t)); - //ratematchpatternid = CALLOC(1,sizeof(NR_RateMatchPatternId_t)); - -} - - -void fix_scc_sim(NR_ServingCellConfigCommon_t *scc,int ssbmap) { - - - int ssbmaplen = (int)scc->ssb_PositionsInBurst->present; - AssertFatal(ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap || ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap || ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap, "illegal ssbmaplen %d\n",ssbmaplen); - if(ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap){ - scc->ssb_PositionsInBurst->choice.shortBitmap.size = 1; - scc->ssb_PositionsInBurst->choice.shortBitmap.bits_unused = 4; - scc->ssb_PositionsInBurst->choice.shortBitmap.buf = CALLOC(1,1); - scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] = ssbmap; - }else if(ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap){ - scc->ssb_PositionsInBurst->choice.mediumBitmap.size = 1; - scc->ssb_PositionsInBurst->choice.mediumBitmap.bits_unused = 0; - scc->ssb_PositionsInBurst->choice.mediumBitmap.buf = CALLOC(1,1); - scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0] = ssbmap; - }else { - scc->ssb_PositionsInBurst->choice.longBitmap.size = 8; - scc->ssb_PositionsInBurst->choice.longBitmap.bits_unused = 0; - scc->ssb_PositionsInBurst->choice.longBitmap.buf = CALLOC(1,8); - scc->ssb_PositionsInBurst->choice.longBitmap.buf[0] = 0xff; - scc->ssb_PositionsInBurst->choice.longBitmap.buf[1] = 0xff; - scc->ssb_PositionsInBurst->choice.longBitmap.buf[2] = 0xff; - scc->ssb_PositionsInBurst->choice.longBitmap.buf[3] = 0xff; - scc->ssb_PositionsInBurst->choice.longBitmap.buf[4] = 0xff; - scc->ssb_PositionsInBurst->choice.longBitmap.buf[5] = 0xff; - scc->ssb_PositionsInBurst->choice.longBitmap.buf[6] = 0xff; - scc->ssb_PositionsInBurst->choice.longBitmap.buf[7] = 0xff; - } - - // fix DL and UL Allocation lists - - for (int i=scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count-1;i>=0;i--) { - if ((int)*scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0==-1) { - free(scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0); - asn_sequence_del(&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list,i,1); - } - } - - for (int i=scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count-1;i>=0;i--) { - if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->k2==-1) { - free(scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->k2); - asn_sequence_del(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,i,1); - } - } - if ((int)scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity == -1) { - free(scc->tdd_UL_DL_ConfigurationCommon->pattern2); - } - - if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) - free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing); -} int main(int argc, char **argv) { char c; int i,aa;//,l; - double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; + double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0; uint8_t snr1set=0; int **txdata; double **s_re,**s_im,**r_re,**r_im; @@ -322,8 +186,6 @@ int main(int argc, char **argv) int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; //int n_errors2, n_alamouti; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; - uint16_t Nid_cell=0; - uint64_t SSB_positions=0x01; channel_desc_t *gNB2UE; //uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0; @@ -340,28 +202,24 @@ int main(int argc, char **argv) //double pbch_sinr; //int pbch_tx_ant; int N_RB_DL=106,mu=1; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config; - uint16_t ssb_periodicity = 10; //unsigned char frame_type = 0; - unsigned char pbch_phase = 0; int frame=0,slot=1; int frame_length_complex_samples; int frame_length_complex_samples_no_prefix; - int slot_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; - nfapi_nr_config_request_t *gNB_config; UE_nr_rxtx_proc_t UE_proc; NR_Sched_Rsp_t Sched_INFO; gNB_MAC_INST *gNB_mac; NR_UE_MAC_INST_t *UE_mac; - - int ret; + int cyclic_prefix_type = NFAPI_CP_NORMAL; int run_initial_sync=0; int do_pdcch_flag=1; - int loglvl=OAILOG_WARNING; + int loglvl=OAILOG_INFO; float target_error_rate = 0.01; int css_flag=0; @@ -374,7 +232,10 @@ int main(int argc, char **argv) randominit(0); - while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dP:IL:E")) != -1) { + int mcsIndex_set=0,rbStart_set=0,rbSize_set=0; + int print_perf = 0; + + while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:")) != -1) { switch (c) { /*case 'f': write_output_file=1; @@ -500,14 +361,6 @@ int main(int argc, char **argv) break; - case 'M': - SSB_positions = atoi(optarg); - break; - - case 'N': - Nid_cell = atoi(optarg); - break; - case 'R': N_RB_DL = atoi(optarg); break; @@ -523,11 +376,8 @@ int main(int argc, char **argv) break; case 'P': - pbch_phase = atoi(optarg); - - if (pbch_phase>3) - printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); - + print_perf=1; + opp_enabled=1; break; case 'I': @@ -539,9 +389,28 @@ int main(int argc, char **argv) loglvl = atoi(optarg); break; + case 'E': css_flag=1; break; + + + case 'a': + dlsch_config.rbStart = atoi(optarg); + rbStart_set=1; + break; + + case 'b': + dlsch_config.rbSize = atoi(optarg); + rbSize_set=1; + break; + + case 'e': + dlsch_config.mcsIndex[0] = atoi(optarg); + mcsIndex_set=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", @@ -554,13 +423,10 @@ int main(int argc, char **argv) printf("-S Ending SNR, runs from SNR0 to SNR1\n"); printf("-t Delay spread for multipath channel\n"); printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); + printf("-y Number of TX antennas used in gNB\n"); printf("-z Number of RX antennas used in UE\n"); - //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-M Multiple SSB positions in burst\n"); - printf("-N Nid_cell\n"); + //printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n"); + //printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n"); printf("-R N_RB_DL\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); @@ -568,11 +434,17 @@ int main(int argc, char **argv) //printf("-f Output filename (.txt format) for Pe/SNR results\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); printf("-E used CSS scheduler\n"); + printf("-o CORESET offset\n"); + printf("-a Start PRB for PDSCH\n"); + printf("-b Number of PRB for PDSCH\n"); + printf("-c Start symbol for PDSCH (fixed for now)\n"); + printf("-j Number of symbols for PDSCH (fixed for now)\n"); + printf("-e MSC index\n"); exit (-1); break; } } - + logInit(); set_glog(loglvl); T_stdout = 1; @@ -580,14 +452,12 @@ int main(int argc, char **argv) if (snr1set==0) snr1 = snr0+10; - printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL); RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB[0] = (PHY_VARS_gNB*) malloc(sizeof(PHY_VARS_gNB )); memset(RC.gNB[0],0,sizeof(PHY_VARS_gNB)); gNB = RC.gNB[0]; - gNB_config = &gNB->gNB_config; 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; @@ -598,50 +468,63 @@ int main(int argc, char **argv) mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; gNB_RRC_INST rrc; - NR_ServingCellConfigCommon_t scc; - rrc.carrier.servingcellconfigcommon = &scc; - prepare_scc_sim(&scc); - *scc.physCellId = Nid_cell; - *scc.subcarrierSpacing=NR_SubcarrierSpacing_kHz30; - *scc.downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB=660960; - *scc.downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]=78; - scc.downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA=660000; - scc.downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier=0; - scc.downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing=NR_SubcarrierSpacing_kHz30; - scc.downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth=N_RB_DL; - scc.downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth=13036; - scc.downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing=NR_SubcarrierSpacing_kHz30; - scc.downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->present=NR_SetupRelease_PDCCH_ConfigCommon_PR_setup; - *scc.downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=12; - *scc.downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero=0; - *scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->k0=0; - scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; - scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength=40; - *scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->k0=0; - scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; - scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength=53; - *scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->k0=0; - scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->mappingType=NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; - scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength=54; - scc.ssb_PositionsInBurst->present=NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap; - scc.tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing=NR_SubcarrierSpacing_kHz30; - scc.tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity=NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p5; - scc.tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity = -1; - for (int i=scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count-1;i>=3;i--) { - *scc.downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0=-1; - } + memset((void*)&rrc,0,sizeof(rrc)); + // read in SCGroupConfig + FILE *scg_fd = fopen("reconfig.raw","r"); + AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); + char buffer[1024]; + int msg_len=fread(buffer,1,1024,scg_fd); + NR_RRCReconfiguration_t *NR_RRCReconfiguration; + + printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len); + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_RRCReconfiguration, + (void **)&NR_RRCReconfiguration, + (uint8_t *)buffer, + msg_len); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"NR_RRCReConfiguration decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, NR_RRCReconfiguration, 1 ); + exit(-1); + } + fclose(scg_fd); + + AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n"); + + NR_RRCReconfiguration_IEs_t *reconfig_ies = NR_RRCReconfiguration->criticalExtensions.choice.rrcReconfiguration; + NR_CellGroupConfig_t *secondaryCellGroup; + dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&secondaryCellGroup, + (uint8_t *)reconfig_ies->secondaryCellGroup->buf, + reconfig_ies->secondaryCellGroup->size); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"NR_CellGroupConfig decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, secondaryCellGroup, 1 ); + exit(-1); + } + + NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); + + rrc.carrier.servingcellconfigcommon = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + printf("%p,%p\n", + secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon, + rrc.carrier.servingcellconfigcommon); - for (int i=scc.uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count-1;i>=0;i--) { - *scc.uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->k2=-1; - } - scc.ssb_PositionsInBurst->present = NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap; - scc.dmrs_TypeA_Position = NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2; - fix_scc_sim(&scc,0xff); AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; - rrc_mac_config_req_gNB(0,0,&scc); + // common configuration + rrc_mac_config_req_gNB(0,0,1,scc,0,0,NULL); + // UE dedicated configuration + rrc_mac_config_req_gNB(0,0,1,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); phy_init_nr_gNB(gNB,0,0); - + N_RB_DL = gNB->frame_parms.N_RB_DL; // stub to configure frame_parms // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); // call MAC to configure common parameters @@ -683,7 +566,6 @@ 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; - slot_length_complex_samples_no_prefix = frame_parms->samples_per_slot_wCP; s_re = malloc(2*sizeof(double*)); s_im = malloc(2*sizeof(double*)); @@ -705,7 +587,7 @@ int main(int argc, char **argv) printf("Allocating %d samples for txdata\n",frame_length_complex_samples); txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); - bzero(r_re[i],frame_length_complex_samples*sizeof(int)); + bzero(txdata[i],frame_length_complex_samples*sizeof(int)); } @@ -744,8 +626,6 @@ int main(int argc, char **argv) nr_l2_init_ue(); UE_mac = get_mac_inst(0); - UE->pdcch_vars[0][0]->crnti = 0x1234; - UE->if_inst = nr_ue_if_module_init(0); UE->if_inst->scheduled_response = nr_ue_scheduled_response; UE->if_inst->phy_config_request = nr_ue_phy_config_request; @@ -755,358 +635,326 @@ int main(int argc, char **argv) UE_mac->if_module = nr_ue_if_module_init(0); - unsigned int available_bits; + unsigned int available_bits=0; unsigned char *estimated_output_bit; unsigned char *test_input_bit; unsigned int errors_bit = 0; uint32_t errors_scrambling = 0; + test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); // generate signal - if (input_fd==NULL) { - gNB->pbch_configured = 1; - for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1; - - if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot); - else nr_schedule_css_dlsch_phytest(0,frame,slot); - - Sched_INFO.module_id = 0; - Sched_INFO.CC_id = 0; - Sched_INFO.frame = frame; - Sched_INFO.slot = slot; - Sched_INFO.DL_req = &gNB_mac->DL_req[0]; - Sched_INFO.UL_req = NULL; - Sched_INFO.HI_DCI0_req = NULL; - Sched_INFO.TX_req = &gNB_mac->TX_req[0]; - nr_schedule_response(&Sched_INFO); - - phy_procedures_gNB_TX(gNB,frame,slot,0); - - //nr_common_signal_procedures (gNB,frame,subframe); - - LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); - if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); - - int tx_offset = slot*frame_parms->samples_per_slot; - - //TODO: loop over slots - for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { - PHY_ofdm_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][tx_offset], - frame_parms->ofdm_symbol_size, - 12, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - } else { - nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][tx_offset], - 14, - frame_parms); - } - } - } else { - printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0); - - if (fread(txdata[0], - sizeof(int32_t), - frame_length_complex_samples, - input_fd) != frame_length_complex_samples) { - printf("error reading from file\n"); - //exit(-1); - } - } - - LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); - if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); - - if (output_fd) - fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd); - - int txlev = signal_energy(&txdata[0][5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], - frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); - - // printf("txlev %d (%f)\n",txlev,10*log10(txlev)); - - for (i=0; inb_antennas_tx; aa++) { - r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); - r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); - } - } + AssertFatal(input_fd==NULL,"Not ready for input signal file\n"); + gNB->pbch_configured = 1; + gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; + + if (mcsIndex_set==0) dlsch_config.mcsIndex[0]=9; + if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL; + if (rbStart_set==0) dlsch_config.rbStart=0; + //Configure UE - uint32_t pdcch_ConfigSIB1 = 0; - uint32_t ssb_SubcarrierOffset = 0; rrc.carrier.MIB = (uint8_t*) malloc(4); rrc.carrier.sizeof_MIB = do_MIB_NR(&rrc,0); - nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,&scc,NULL,NULL,NULL); + nr_rrc_mac_config_req_ue(0,0,0,rrc.carrier.mib.message.choice.mib,scc,secondaryCellGroup->spCellConfig); - // Initial bandwidth part configuration -- full carrier bandwidth - UE_mac->initial_bwp_dl.bwp_id = 0; - UE_mac->initial_bwp_dl.location = 0; - UE_mac->initial_bwp_dl.scs = UE->frame_parms.subcarrier_spacing; - UE_mac->initial_bwp_dl.N_RB = UE->frame_parms.N_RB_DL; - UE_mac->initial_bwp_dl.cyclic_prefix = UE->frame_parms.Ncp; - - fapi_nr_dl_config_request_t *dl_config = &UE_mac->dl_config_request; - // Type0 PDCCH search space - dl_config->number_pdus = 1; - dl_config->dl_config_list[0].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.rnti = 0x1234; - - uint64_t mask = 0x0; - uint16_t num_rbs=24; - uint16_t rb_offset=0; - uint16_t cell_id=0; - uint16_t num_symbols=2; - for(i=0; i<(num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs - mask = mask >> 1; - mask = mask | 0x100000000000; - } - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.frequency_domain_resource = mask; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.rb_offset = rb_offset; // additional parameter other than coreset - - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.duration = num_symbols; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_mapping_type =CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_reg_bundle_size = 0; // L 38.211 7.3.2.2 - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_interleaver_size = 0; // R 38.211 7.3.2.2 - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_shift_index = cell_id; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.pdcch_dmrs_scrambling_id = cell_id; - uint8_t gnb_start_symbol = Sched_INFO.DL_req->dl_config_request_body.dl_config_pdu_list[1].dlsch_pdu.dlsch_pdu_rel15.start_symbol; - dl_config->dl_config_list[0].dlsch_config_pdu.dlsch_config_rel15.start_symbol = gnb_start_symbol; - - uint32_t number_of_search_space_per_slot=1; - uint32_t first_symbol_index=0; - uint32_t search_space_duration=0; // element of search space - uint32_t coreset_duration; // element of coreset - - coreset_duration = num_symbols * number_of_search_space_per_slot; - - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[0] = table_38213_10_1_1_c2[0]; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[1] = table_38213_10_1_1_c2[1]; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[2] = table_38213_10_1_1_c2[2]; // CCE aggregation level = 4 - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[3] = table_38213_10_1_1_c2[3]; // CCE aggregation level = 8 - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16 - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.duration = search_space_duration; - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff; - - dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.N_RB_BWP = N_RB_DL; - - UE_mac->scheduled_response.dl_config = dl_config; - UE_mac->scheduled_response.ul_config = NULL; - UE_mac->scheduled_response.tx_request = NULL; - UE_mac->scheduled_response.module_id = 0; - UE_mac->scheduled_response.CC_id = 0; - UE_mac->scheduled_response.frame = frame; - UE_mac->scheduled_response.slot = slot; + nr_dcireq_t dcireq; + nr_scheduled_response_t scheduled_response; + memset((void*)&dcireq,0,sizeof(dcireq)); + memset((void*)&scheduled_response,0,sizeof(scheduled_response)); + dcireq.module_id = 0; + dcireq.gNB_index = 0; + dcireq.cc_id = 0; + + scheduled_response.dl_config = &dcireq.dl_config_req; + scheduled_response.ul_config = &dcireq.ul_config_req; + scheduled_response.tx_request = NULL; + scheduled_response.module_id = 0; + scheduled_response.CC_id = 0; + scheduled_response.frame = frame; + scheduled_response.slot = slot; + nr_ue_phy_config_request(&UE_mac->phy_config); for (SNR = snr0; SNR < snr1; SNR += .2) { + varArray_t *table_tx=initVarArray(1000,sizeof(double)); + reset_meas(&gNB->phy_proc_tx); // total gNB tx + reset_meas(&gNB->dlsch_scrambling_stats); + reset_meas(&gNB->dlsch_interleaving_stats); + reset_meas(&gNB->dlsch_rate_matching_stats); + reset_meas(&gNB->dlsch_segmentation_stats); + reset_meas(&gNB->dlsch_modulation_stats); + reset_meas(&gNB->dlsch_encoding_stats); + reset_meas(&gNB->tinput); + reset_meas(&gNB->tprep); + reset_meas(&gNB->tparity); + reset_meas(&gNB->toutput); + n_errors = 0; //n_errors2 = 0; //n_alamouti = 0; - + errors_scrambling=0; + n_false_positive = 0; for (trial = 0; trial < n_trials; trial++) { + errors_bit = 0; //multipath channel //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0); + + memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int)); + clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); + if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&dlsch_config); + else nr_schedule_css_dlsch_phytest(0,frame,slot); + + + Sched_INFO.module_id = 0; + Sched_INFO.CC_id = 0; + Sched_INFO.frame = frame; + Sched_INFO.slot = slot; + Sched_INFO.DL_req = &gNB_mac->DL_req[0]; + Sched_INFO.UL_tti_req = &gNB_mac->UL_tti_req[0]; + Sched_INFO.UL_dci_req = NULL; + Sched_INFO.TX_req = &gNB_mac->TX_req[0]; + nr_schedule_response(&Sched_INFO); + + phy_procedures_gNB_TX(gNB,frame,slot,0); + + //nr_common_signal_procedures (gNB,frame,subframe); + int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP; + + if (n_trials==1) { + LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); + } + int tx_offset = slot*frame_parms->samples_per_slot; + if (n_trials==1) printf("samples_per_slot_wCP = %d\n", frame_parms->samples_per_slot_wCP); + + //TODO: loop over slots + for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + + if (cyclic_prefix_type == 1) { + PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], + &txdata[aa][tx_offset], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } else { + nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], + &txdata[aa][tx_offset], + 14, + frame_parms); + } + } + + if (n_trials==1) { + LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); + } + if (output_fd) + fwrite(txdata[0],sizeof(int32_t),frame_length_complex_samples,output_fd); + + int txlev = signal_energy(&txdata[0][(slot*frame_parms->samples_per_slot)+5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + + // if (n_trials==1) printf("txlev %d (%f)\n",txlev,10*log10((double)txlev)); + + for (i=(slot * frame_parms->samples_per_slot); + i<((slot+1) * frame_parms->samples_per_slot); + i++) { + for (aa=0; aanb_antennas_tx; aa++) { + r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); + r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); + } + } + + NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t rel15 = gNB_dlsch->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15; //AWGN - sigma2_dB = 10 * log10((double)txlev) - SNR; + sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15.rbSize))) - SNR; sigma2 = pow(10, sigma2_dB/10); - // printf("sigma2 %f (%f dB)\n",sigma2,sigma2_dB); - - for (i=0; iframe_parms.ofdm_symbol_size/(12*rel15.rbSize)); + + for (i=(slot * frame_parms->samples_per_slot); + i<((slot+1) * frame_parms->samples_per_slot); + i++) { for (aa=0; aanb_antennas_rx; aa++) { ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } - - if (n_trials == 1) { - - LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1); - if (UE->frame_parms.nb_antennas_rx>1) - LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); - - } - - if (UE->is_synchronized == 0) { - - UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, normal_txrx,1); - printf("nr_initial_sync1 returns %d\n",ret); - if (ret<0) n_errors++; - } - else { - UE->rx_offset=0; - - UE_proc.frame_rx = frame; - UE_proc.nr_tti_rx= slot; - UE_proc.subframe_rx = slot; + + UE->rx_offset=0; + UE_proc.frame_rx = frame; + UE_proc.nr_tti_rx= slot; + UE_proc.subframe_rx = slot; + + dcireq.frame = frame; + dcireq.slot = slot; + + nr_ue_dcireq(&dcireq); //to be replaced with function pointer later + nr_ue_scheduled_response(&scheduled_response); + + phy_procedures_nrUE_RX(UE, + &UE_proc, + 0, + do_pdcch_flag, + normal_txrx); + + if (UE->dlsch[UE->current_thread_id[slot]][0][0]->last_iteration_cnt >= + UE->dlsch[UE->current_thread_id[slot]][0][0]->max_ldpc_iterations+1) + n_errors++; + + //---------------------------------------------------------- + //---------------------- count errors ---------------------- + //---------------------------------------------------------- + + + + NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0]; + + int harq_pid = dlsch0->current_harq_pid; + NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid]; + + NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]]; + int16_t *UE_llr = pdsch_vars[0]->llr[0]; + + + uint32_t TBS = rel15.TBSize[0]; + uint16_t length_dmrs = 1; + uint16_t nb_rb = rel15.rbSize; + uint8_t nb_re_dmrs = rel15.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4; + uint8_t mod_order = rel15.qamModOrder[0]; + uint8_t nb_symb_sch = rel15.NrOfSymbols; + + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15.nrOfLayers); + + for (i = 0; i < available_bits; i++) { - nr_ue_scheduled_response(&UE_mac->scheduled_response); - - printf("Running phy procedures UE RX %d.%d\n",frame,slot); - - phy_procedures_nrUE_RX(UE, - &UE_proc, - 0, - do_pdcch_flag, - normal_txrx, - &UE_mac->dl_config_request); - - if (n_trials==1) { - LOG_M("rxsigF0.m","rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],slot_length_complex_samples_no_prefix,1,1); - if (UE->frame_parms.nb_antennas_rx>1) - LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[1],slot_length_complex_samples_no_prefix,1,1); + if(((gNB_dlsch->harq_processes[harq_pid]->f[i] == 0) && (UE_llr[i] <= 0)) || + ((gNB_dlsch->harq_processes[harq_pid]->f[i] == 1) && (UE_llr[i] >= 0))) + { + if(errors_scrambling == 0) { + LOG_D(PHY,"\n"); + LOG_D(PHY,"First bit in error in unscrambling = %d\n",i); + } + errors_scrambling++; + } + + } + + for (i = 0; i < TBS; i++) { + + estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7); + test_input_bit[i] = (gNB_dlsch->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments + + if (estimated_output_bit[i] != test_input_bit[i]) { + if(errors_bit == 0) + LOG_D(PHY,"First bit in error in decoding = %d (errors scrambling %d)\n",i,errors_scrambling); + errors_bit++; } - if (UE_mac->dl_config_request.number_pdus==0) n_errors++; } - } //noise trials - - - UE_nr_rxtx_proc_t proc = {0}; - ret = nr_initial_sync(&proc, UE, normal_txrx, 1); - printf("nr_initial_sync1 returns %d\n", ret); - - if (ret < 0) - n_errors++; - - } else { // UE->is_synchronized != 0 - - UE->rx_offset = 0; - UE_proc.frame_rx = frame; - UE_proc.nr_tti_rx = slot; - UE_proc.subframe_rx = slot; - - nr_ue_scheduled_response(&UE_mac->scheduled_response); - - printf("Running phy procedures UE RX %d.%d\n", frame, slot); - - phy_procedures_nrUE_RX(UE, - &UE_proc, - 0, - do_pdcch_flag, - normal_txrx); - - if (n_trials == 1) { - - LOG_M("rxsigF0.m","rxsF0", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0], slot_length_complex_samples_no_prefix, 1, 1); - if (UE->frame_parms.nb_antennas_rx > 1) - LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[0].rxdataF[1], slot_length_complex_samples_no_prefix, 1, 1); - - } - - if (UE_mac->dl_config_request.number_pdus == 0) - n_errors++; - - //---------------------------------------------------------- - //---------------------- count errors ---------------------- - //---------------------------------------------------------- - - NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0]; - - NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0]; - int harq_pid = dlsch0->current_harq_pid; - NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid]; - - NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]]; - int16_t *UE_llr = pdsch_vars[0]->llr[0]; - - nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = gNB_dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; - uint32_t TBS = rel15.transport_block_size; - uint16_t length_dmrs = 1; - uint16_t nb_rb = rel15.n_prb; - uint8_t nb_re_dmrs = rel15.nb_re_dmrs; - uint8_t mod_order = rel15.modulation_order; - uint8_t nb_symb_sch = rel15.nb_symbols; - - available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15.nb_layers); - - printf("\n"); - printf("available_bits = %d\n",available_bits); - - for (i = 0; i < available_bits; i++) { - - if(((gNB_dlsch->harq_processes[harq_pid]->f[i] == 0) && (UE_llr[i] <= 0)) || - ((gNB_dlsch->harq_processes[harq_pid]->f[i] == 1) && (UE_llr[i] >= 0))) - { - if(errors_scrambling == 0) { - printf("\n"); - printf("First bit in error in unscrambling = %d\n",i); - } - errors_scrambling++; - } - - } - - for (i = 0; i < TBS; i++) { - - estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7); - test_input_bit[i] = (gNB_dlsch->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments - - if (estimated_output_bit[i] != test_input_bit[i]) { - if(errors_bit == 0) - printf("First bit in error in decoding = %d\n",i); - errors_bit++; - } - - } - - //////////////////////////////////////////////////////////// - - if (errors_scrambling > 0) { - if (n_trials == 1) - printf("errors_scrambling = %d (trial %d)\n", errors_scrambling, trial); - } - - if (errors_bit > 0) { - n_false_positive++; - if (n_trials == 1) - printf("errors_bit = %d (trial %d)\n", errors_bit, trial); - } - - printf("\n"); - - } // if (UE->is_synchronized == 0) - + + //////////////////////////////////////////////////////////// + + if (errors_scrambling > 0) { + if (n_trials == 1) + printf("errors_scrambling = %d/%d (trial %d)\n", errors_scrambling, available_bits,trial); + } + + if (errors_bit > 0) { + n_false_positive++; + if (n_trials == 1) + printf("errors_bit = %u (trial %d)\n", errors_bit, trial); + } + } // noise trials printf("*****************************************\n"); printf("SNR %f, (false positive %f)\n", SNR, - (float) n_false_positive / (float) n_trials); + (float) n_errors / (float) n_trials); printf("*****************************************\n"); printf("\n"); - - if (errors_bit == 0) { - printf("PDSCH test OK\n"); - printf("\n"); - } - - printf("SNR %f : n_errors (negative CRC) = %d/%d\n", SNR, n_errors, n_trials); + printf("SNR %f : n_errors (negative CRC) = %d/%d, Channel BER %e\n", SNR, n_errors, n_trials,(double)errors_scrambling/available_bits/n_trials); printf("\n"); - if ((float)n_errors/(float)n_trials <= target_error_rate) { - printf("PDCCH test OK\n"); + if (n_trials == 1) { + + LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1); + if (UE->frame_parms.nb_antennas_rx>1) + LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); + LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1); + write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1); break; } - - if (n_trials == 1) - break; + if ((float)n_errors/(float)n_trials <= target_error_rate) { + printf("PDSCH test OK\n"); + break; + } + + + if (print_perf==1) { + printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n", + 1000>>*scc->ssbSubcarrierSpacing,dlsch_config.rbSize,dlsch_config.mcsIndex[0], + gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3, + gNB->dlsch[0][0]->harq_processes[0]->K, + gNB->dlsch[0][0]->harq_processes[0]->K/((gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3)>3824?22:10)); + printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx"); + printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time"); + printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time"); + printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time"); + printStatIndent3(&gNB->tprep,"DLSCH LDPC input preparation time"); + printStatIndent3(&gNB->tparity,"DLSCH LDPC parity generation time"); + printStatIndent3(&gNB->toutput,"DLSCH LDPC output generation time"); + printStatIndent3(&gNB->dlsch_rate_matching_stats,"DLSCH Rate Mataching time"); + printStatIndent3(&gNB->dlsch_interleaving_stats, "DLSCH Interleaving time"); + printStatIndent2(&gNB->dlsch_modulation_stats,"DLSCH modulation time"); + printStatIndent2(&gNB->dlsch_scrambling_stats, "DLSCH scrambling time"); + + + printf("\nUE RX function statistics (per %d us slot)\n",1000>>*scc->ssbSubcarrierSpacing); + /* + printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx"); + printStatIndent(&ue_front_end_tot,"Front end processing"); + printStatIndent(&dlsch_llr_tot,"rx_pdsch processing"); + printStatIndent2(&pdsch_procedures_tot,"pdsch processing"); + printStatIndent2(&dlsch_procedures_tot,"dlsch processing"); + printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing"); + printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation"); + printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time"); + printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time"); + printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time "); + printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time"); + printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching"); + printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, + UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials, + (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase, + (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials), + UE->dlsch_turbo_decoding_stats.trials); + printStatIndent2(&UE->dlsch_tc_init_stats,"init"); + printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha"); + printStatIndent2(&UE->dlsch_tc_beta_stats,"beta"); + printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma"); + printStatIndent2(&UE->dlsch_tc_ext_stats,"ext"); + printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver"); + printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC"); + */ + } } // NSR for (i = 0; i < 2; i++) { @@ -1132,5 +980,5 @@ int main(int argc, char **argv) fclose(input_fd); return(n_errors); - + } diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index ae47b11b2f..c9253aeedf 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -2,7 +2,7 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); } +//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); } int32_t get_uldl_offset(int nr_bandP) { return(0); } NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h index be04bc8213..78596cc792 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h @@ -41,7 +41,7 @@ void exit_function(const char* file, const char* function, const int line, const exit(-1); } -char quantize(double D, double x, unsigned char B) { +signed char quantize(double D, double x, unsigned char B) { double qxd; short maxlev; qxd = floor(x / D); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 6afdb3d4e3..fcb5b56086 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -52,27 +52,13 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + double cpuf; int nfapi_mode=0; -int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } -int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } - -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {return(0);} - -uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn) {return(0);} -int32_t get_nr_uldl_offset(int nr_bandP) {return(0);} - -NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} - -void exit_function(const char* file, const char* function, const int line,const char *s) { - const char * msg= s==NULL ? "no comment": s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); -} +uint16_t NB_UE_INST = 1; // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; @@ -127,7 +113,6 @@ int main(int argc, char **argv) int frame_length_complex_samples; int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; - nfapi_nr_config_request_t *gNB_config; int ret, payload_ret=0; int run_initial_sync=0; @@ -362,7 +347,6 @@ int main(int argc, char **argv) RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB)); gNB = RC.gNB[0]; - gNB_config = &gNB->gNB_config; 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; @@ -375,7 +359,8 @@ int main(int argc, char **argv) nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,0); - uint8_t n_hf = gNB_config->sch_config.half_frame_index.value; + uint8_t n_hf = 0; + int cyclic_prefix_type = NFAPI_CP_NORMAL; double fs,bw,scs,eps; @@ -484,7 +469,8 @@ int main(int argc, char **argv) // generate signal if (input_fd==NULL) { gNB->pbch_configured = 1; - for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1; + + gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0; for (int slot=0;slotslots_per_frame;slot++) { for (aa=0; aaframe_parms.nb_antennas_tx; aa++) @@ -493,18 +479,18 @@ int main(int argc, char **argv) nr_common_signal_procedures (gNB,frame,slot); for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { + if (cyclic_prefix_type == 1) { PHY_ofdm_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][slot*frame_parms->samples_per_slot], - frame_parms->ofdm_symbol_size, - 12, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); + &txdata[aa][slot*frame_parms->samples_per_slot], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); } else { nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], - &txdata[aa][slot*frame_parms->samples_per_slot], - 14, - frame_parms); + &txdata[aa][slot*frame_parms->samples_per_slot], + 14, + frame_parms); } } } @@ -603,7 +589,7 @@ int main(int argc, char **argv) UE->rx_offset=0; uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb - UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index, n_hf); + UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms, ssb_index); int ssb_slot = (ssb_index/2)+(n_hf*frame_parms->slots_per_frame); for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { nr_slot_fep(UE, @@ -635,8 +621,7 @@ int main(int argc, char **argv) payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte); for (i=0;i<3;i++){ - payload_ret += (UE->pbch_vars[0]->decoded_output[i] == gNB->pbch_pdu[2-i]); - //printf("pdu byte %d gNB: 0x%02x UE: 0x%02x\n",i,gNB->pbch_pdu[i], UE->rx_ind.rx_indication_body->mib_pdu.pdu[i]); + payload_ret += (UE->pbch_vars[0]->decoded_output[i] == (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i))); } //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->rx_ind.rx_indication_body->mib_pdu.additional_bits); //printf("ret %d\n", payload_ret); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index f3a83870d6..80eed8063d 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -50,7 +50,7 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; -RU_t *RU; +RU_t *ru; double cpuf; @@ -58,6 +58,9 @@ extern uint16_t prach_root_sequence_map0_3[838]; void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe); +uint16_t NB_UE_INST=1; +volatile int oai_exit=0; + void exit_function(const char* file, const char* function, const int line,const char *s) { const char * msg= s==NULL ? "no comment": s; printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); @@ -70,8 +73,6 @@ int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t e return 0; } -int32_t get_nr_uldl_offset(int nr_bandP) {return(0);} - int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);} openair0_config_t openair0_cfg[MAX_CARDS]; @@ -79,9 +80,6 @@ int nfapi_mode=0; NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {return(0);} -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } -uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn) {return(0);} int main(int argc, char **argv) { @@ -132,7 +130,7 @@ int main(int argc, char **argv) cpuf = get_cpu_freq_GHz(); - if ( load_configmodule(argc,argv) == 0) { + if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } @@ -358,7 +356,7 @@ int main(int argc, char **argv) RC.nb_RU = 1; gNB = RC.gNB[0]; - RU = RC.ru[0]; + ru = RC.ru[0]; if (ue_speed1set==0) { @@ -397,10 +395,10 @@ int main(int argc, char **argv) printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d,Frame type %s, Frequency Range %s\n",NUMBER_OF_OFDM_CARRIERS, frame_parms->Ncp,frame_parms->samples_per_slot<<1,frame_parms->frame_type == FDD ? "FDD" : "TDD", frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2"); - RU->nr_frame_parms=frame_parms; - RU->if_south = LOCAL_RF; - RU->nb_tx = n_tx; - RU->nb_rx = n_rx; + ru->nr_frame_parms=frame_parms; + ru->if_south = LOCAL_RF; + ru->nb_tx = n_tx; + ru->nb_rx = n_rx; RC.nb_nr_L1_inst=1; phy_init_nr_gNB(gNB,0,0); @@ -480,7 +478,7 @@ int main(int argc, char **argv) gNB->proc.slot_rx = subframe<<1; - gNB->common_vars.rxdata = RU->common.rxdata; + gNB->common_vars.rxdata = ru->common.rxdata; compute_nr_prach_seq(gNB->frame_parms.prach_config_common.rootSequenceIndex, @@ -595,7 +593,7 @@ nr_ue_prach_procedures(UE,&proc,0,0,0); rx_nr_prach_ru(RU, 0, subframe); - gNB->prach_vars.rxsigF = RU->prach_rxsigF; + gNB->prach_vars.rxsigF = ru->prach_rxsigF; rx_nr_prach(gNB, 0, diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index fb4fb744a8..6af2837901 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -50,28 +50,11 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; openair0_config_t openair0_cfg[MAX_CARDS]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + double cpuf; int nfapi_mode=0; - -int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } - -int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } - -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } - -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {return(0);} - -uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn) {return(0);} -int32_t get_nr_uldl_offset(int nr_bandP) {return(0);} - -NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} - -void exit_function(const char* file, const char* function, const int line,const char *s) { - const char * msg= s==NULL ? "no comment": s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); -} +uint16_t NB_UE_INST = 1; // needed for some functions PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}}; @@ -333,6 +316,9 @@ int main(int argc, char **argv) frame_parms->N_RB_UL = N_RB_DL; frame_parms->Nid_cell = Nid_cell; + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; + cfg->carrier_config.num_tx_ant.value = n_tx; + cfg->carrier_config.num_rx_ant.value = n_rx; nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,0); diff --git a/openair1/SIMULATION/NR_PHY/reconfig.raw b/openair1/SIMULATION/NR_PHY/reconfig.raw new file mode 100644 index 0000000000..59b524fbba Binary files /dev/null and b/openair1/SIMULATION/NR_PHY/reconfig.raw differ diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 7febb6cb28..41a93ada66 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -52,45 +52,11 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + double cpuf; int nfapi_mode = 0; - -int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { - return (0); -} -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { - return (0); -} - -int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { - return (0); -} - -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { - return (0); -} - -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { - return (0); -} - -uint32_t from_nrarfcn(int nr_bandP, uint32_t dl_earfcn) { - return (0); -} -int32_t get_nr_uldl_offset(int eutra_bandP) { - return (0); -} - -NR_IF_Module_t * -NR_IF_Module_init(int Mod_id) { - return (NULL); -} - -void exit_function(const char *file, const char *function, const int line, const char *s) { - const char *msg = s == NULL ? "no comment" : s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); -} +uint16_t NB_UE_INST = 1; // needed for some functions PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } }; @@ -101,7 +67,7 @@ int main(int argc, char **argv) { char c; int i,sf; - double SNR, snr0 = -2.0, snr1 = 2.0; //, SNR_lin; + double SNR, snr0 = -2.0, snr1 = 2.0, SNR_lin; double snr_step = 0.1; uint8_t snr1set = 0; FILE *output_fd = NULL; @@ -120,7 +86,7 @@ int main(int argc, char **argv) //unsigned char pbch_phase = 0; int frame = 0, subframe = 0; NR_DL_FRAME_PARMS *frame_parms; - //double sigma; + double sigma; unsigned char qbits = 8; int ret; int loglvl = OAILOG_WARNING; @@ -410,22 +376,23 @@ int main(int argc, char **argv) uint8_t nb_re_dmrs = 6; uint8_t length_dmrs = 1; uint8_t N_PRB_oh; - uint16_t N_RE_prime; + uint16_t N_RE_prime,code_rate; unsigned char mod_order; uint8_t Nl = 1; uint8_t rvidx = 0; uint8_t UE_id = 0; - NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id+1][0]; + NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0]; - mod_order = nr_get_Qm(Imcs, 1); + mod_order = nr_get_Qm_ul(Imcs, 0); + code_rate = nr_get_code_rate_ul(Imcs, 0); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl); - printf("\n"); - printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order); + TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl); + + printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); /////////// setting rel15_ul parameters /////////// rel15_ul->number_rbs = nb_rb; @@ -436,6 +403,7 @@ int main(int argc, char **argv) rel15_ul->n_layers = Nl; rel15_ul->nb_re_dmrs = nb_re_dmrs; rel15_ul->length_dmrs = length_dmrs; + rel15_ul->R = code_rate; /////////////////////////////////////////////////// double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc @@ -487,7 +455,7 @@ int main(int argc, char **argv) //////////////////////////////////////////////////////////////////////////////////////////// #ifdef DEBUG_NR_ULSCHSIM - for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]); + for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%hhu \n",test_input[i]); #endif /////////////////////////ULSCH coding///////////////////////// @@ -529,11 +497,15 @@ int main(int argc, char **argv) //if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]); - //SNR_lin = pow(10, SNR / 10.0); - //sigma = 1.0 / sqrt(2 * SNR_lin); +#if 1 + SNR_lin = pow(10, SNR / 10.0); + sigma = 1.0 / sqrt(2 * SNR_lin); + channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0, + modulated_input[i] + sigma * gaussdouble(0.0, 1.0), + qbits); +#else channel_output_fixed[i] = (short) quantize(0.01, modulated_input[i], qbits); - //channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0, modulated_input[i] + sigma * gaussdouble(0.0, 1.0), qbits); - //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0)); +#endif //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]); //Uncoded BER @@ -545,9 +517,10 @@ int main(int argc, char **argv) if (channel_output_uncoded[i] != ulsch_ue->harq_processes[harq_pid]->f[i]) errors_bit_uncoded = errors_bit_uncoded + 1; } - +/* printf("errors bits uncoded %u\n", errors_bit_uncoded); printf("\n"); +*/ #ifdef DEBUG_CODER printf("\n"); exit(-1); @@ -570,13 +543,13 @@ int main(int argc, char **argv) errors_bit++; } } - +/* if (errors_bit > 0) { n_false_positive++; if (n_trials == 1) - printf("errors_bit %d (trial %d)\n", errors_bit, trial); + printf("errors_bit %u (trial %d)\n", errors_bit, trial); } - printf("\n"); + printf("\n");*/ } printf("*****************************************\n"); @@ -586,7 +559,7 @@ int main(int argc, char **argv) printf("*****************************************\n"); printf("\n"); - if (errors_bit == 0) { + if (n_errors == 0) { printf("PUSCH test OK\n"); printf("\n"); break; @@ -594,30 +567,6 @@ int main(int argc, char **argv) printf("\n"); } - for (i = 0; i < 2; i++) { - - printf("----------------------\n"); - printf("freeing codeword %d\n", i); - printf("----------------------\n"); - - printf("gNB ulsch[0][%d]\n", i); // [hna] ulsch[0] is for RA - - free_gNB_ulsch(gNB->ulsch[0][i]); - - printf("gNB ulsch[%d][%d]\n",UE_id+1, i); - - free_gNB_ulsch(gNB->ulsch[UE_id+1][i]); - - for (sf = 0; sf < 2; sf++) { - - printf("UE ulsch[%d][0][%d]\n", sf, i); - - if (UE->ulsch[sf][0][i]) - free_nr_ue_ulsch(UE->ulsch[sf][0][i]); - } - - printf("\n"); - } if (output_fd) fclose(output_fd); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index cbc073d26c..a9b268ee27 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -54,52 +54,69 @@ #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" //#define DEBUG_ULSIM PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + double cpuf; int nfapi_mode = 0; +uint16_t NB_UE_INST = 1; -int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { - return (0); -} -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { - return (0); -} - -int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { - return (0); -} - -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { - return (0); -} - -int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { - return (0); -} - -int32_t get_uldl_offset(int eutra_bandP) { - return (0); -} - -NR_IF_Module_t * -NR_IF_Module_init(int Mod_id) { - return (NULL); -} - -void exit_function(const char *file, const char *function, const int line, const char *s) { - const char *msg = s == NULL ? "no comment" : s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); -} - -// dummy functions int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; } +void mac_rlc_data_ind ( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + char *buffer_pP, + const tb_size_t tb_sizeP, + num_tb_t num_tbP, + crc_t *crcs_pP){} +mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id) +{mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;} +tbs_size_t mac_rlc_data_req( const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + char *buffer_pP, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id ) +{return 0;} +int generate_dlsch_header(unsigned char *mac_header, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding){return 0;} +uint64_t get_softmodem_optmask(void) {return 0;} +int rlc_module_init (int enb) {return(0);} +void pdcp_layer_init (void) {} +void nr_ip_over_LTE_DRB_preconfiguration(void){} // needed for some functions uint16_t n_rnti = 0x1234; @@ -116,7 +133,7 @@ int main(int argc, char **argv) int slot = 0; FILE *output_fd = NULL; //uint8_t write_output_file = 0; - int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; + int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0; uint8_t n_tx = 1, n_rx = 1; //uint8_t transmission_mode = 1; uint16_t Nid_cell = 0; @@ -127,7 +144,7 @@ int main(int argc, char **argv) SCM_t channel_model = AWGN; //Rayleigh1_anticorr; uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; //unsigned char frame_type = 0; - int frame = 0; + int number_of_frames = 1; int frame_length_complex_samples; NR_DL_FRAME_PARMS *frame_parms; int loglvl = OAILOG_WARNING; @@ -142,10 +159,9 @@ int main(int argc, char **argv) int tx_offset; double txlev_float; int32_t txlev; - int start_rb = 30; + int start_rb = 0; int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault) - cpuf = get_cpu_freq_GHz(); @@ -159,8 +175,21 @@ int main(int argc, char **argv) //logInit(); randominit(0); - while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:")) != -1) { + while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:P:R:S:L:")) != -1) { switch (c) { + + /*case 'd': + frame_type = 1; + break;*/ + + case 'd': + delay = atoi(optarg); + break; + + case 'f': + number_of_frames = atoi(optarg); + break; + /*case 'f': write_output_file = 1; output_fd = fopen(optarg, "w"); @@ -172,10 +201,6 @@ int main(int argc, char **argv) break;*/ - /*case 'd': - frame_type = 1; - break;*/ - case 'g': switch ((char) *optarg) { case 'A': @@ -221,25 +246,31 @@ int main(int argc, char **argv) interf2 = atoi(optarg); break;*/ + case 'l': + nb_symb_sch = atoi(optarg); + break; + + case 'm': + Imcs = atoi(optarg); + break; + case 'n': n_trials = atoi(optarg); break; + case 'p': + extended_prefix_flag = 1; + break; + + case 'r': + nb_rb = atoi(optarg); + break; + case 's': snr0 = atof(optarg); printf("Setting SNR0 to %f\n", snr0); break; - case 'S': - snr1 = atof(optarg); - snr1set = 1; - printf("Setting SNR1 to %f\n", snr1); - break; - - case 'p': - extended_prefix_flag = 1; - break; - /* case 'r': ricean_factor = pow(10,-.1*atof(optarg)); @@ -250,6 +281,10 @@ int main(int argc, char **argv) break; */ + /*case 'x': + transmission_mode = atoi(optarg); + break;*/ + case 'y': n_tx = atoi(optarg); @@ -270,6 +305,16 @@ int main(int argc, char **argv) break; + case 'F': + input_fd = fopen(optarg, "r"); + + if (input_fd == NULL) { + printf("Problem with filename %s\n", optarg); + exit(-1); + } + + break; + case 'M': SSB_positions = atoi(optarg); break; @@ -283,56 +328,43 @@ int main(int argc, char **argv) N_RB_UL = N_RB_DL; break; - case 'F': - input_fd = fopen(optarg, "r"); - - if (input_fd == NULL) { - printf("Problem with filename %s\n", optarg); - exit(-1); - } - + case 'S': + snr1 = atof(optarg); + snr1set = 1; + printf("Setting SNR1 to %f\n", snr1); break; - case 'm': - Imcs = atoi(optarg); - break; - - case 'l': - nb_symb_sch = atoi(optarg); - break; - - case 'r': - nb_rb = atoi(optarg); - break; - - /*case 'x': - transmission_mode = atoi(optarg); - break;*/ + case 'L': + loglvl = atoi(optarg); + 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]); - printf("-h This message\n"); - printf("-p Use extended prefix mode\n"); //printf("-d Use TDD\n"); - printf("-n Number of frames to simulate\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); + printf("-d Introduce delay in terms of number of samples\n"); + printf("-f Number of frames to simulate\n"); printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-h This message\n"); + //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n"); + printf("-m MCS value\n"); + printf("-n Number of trials to simulate\n"); + printf("-p Use extended prefix mode\n"); + printf("-t Delay spread for multipath channel\n"); //printf("-x Transmission mode (1,2,6 for the moment)\n"); printf("-y Number of TX antennas used in eNB\n"); printf("-z Number of RX antennas used in UE\n"); - //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-M Multiple SSB positions in burst\n"); - printf("-N Nid_cell\n"); - printf("-R N_RB_DL\n"); - printf("-O oversampling factor (1,2,4,8,16)\n"); + 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 Output filename (.txt format) for Pe/SNR results\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); + printf("-M Multiple SSB positions in burst\n"); + printf("-N Nid_cell\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-R N_RB_DL\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); exit(-1); break; } @@ -359,13 +391,6 @@ int main(int argc, char **argv) RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB)); gNB = RC.gNB[0]; //gNB_config = &gNB->gNB_config; - gNB_L1_rxtx_proc_t gNB_proc; - - gNB_proc.frame_rx = frame; - gNB_proc.slot_rx = slot; - - UE_proc.nr_tti_tx = slot; - UE_proc.frame_tx = frame; frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) frame_parms->nb_antennas_tx = n_tx; @@ -376,7 +401,7 @@ int main(int argc, char **argv) crcTableInit(); - nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell, SSB_positions); + nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions); phy_init_nr_gNB(gNB, 0, 0); //init_eNB_afterRU(); @@ -413,210 +438,251 @@ int main(int argc, char **argv) } } - unsigned char harq_pid = 0; - unsigned int TBS = 8424; + unsigned int TBS; unsigned int available_bits; - uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4; + uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1?6:4); uint8_t length_dmrs = 1; unsigned char mod_order; + uint16_t code_rate; - mod_order = nr_get_Qm(Imcs, 1); + mod_order = nr_get_Qm_ul(Imcs, 0); + code_rate = nr_get_code_rate_ul(Imcs, 0); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, precod_nbr_layers); + TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers); + + NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; + //nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu; + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; - NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id+1][0]; - nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu; - NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0]; - - // --------- setting rel15_ul parameters for gNB -------- - rel15_ul->rnti = n_rnti; - rel15_ul->ulsch_pdu_rel15.start_rb = start_rb; - rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb; - rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol; - rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch; - rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = nb_re_dmrs; - rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs; - rel15_ul->ulsch_pdu_rel15.Qm = mod_order; - rel15_ul->ulsch_pdu_rel15.mcs = Imcs; - rel15_ul->ulsch_pdu_rel15.rv = 0; - rel15_ul->ulsch_pdu_rel15.ndi = 0; - rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers; - /////////////////////////////////////////////////// - - nr_scheduled_response_t scheduled_response; - fapi_nr_ul_config_request_t ul_config; - //fapi_nr_tx_request_t tx_request; - - scheduled_response.module_id = 0; - scheduled_response.CC_id = 0; - scheduled_response.frame = frame; - scheduled_response.slot = slot; - scheduled_response.dl_config = NULL; - scheduled_response.ul_config = &ul_config; - scheduled_response.dl_config = NULL; - - ul_config.sfn_slot = slot; - ul_config.number_pdus = 1; - ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_ULSCH; - ul_config.ul_config_list[0].ulsch_config_pdu.rnti = n_rnti; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = Imcs; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = 0; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers; - ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid; - //there are plenty of other parameters that we don't seem to be using for now. e.g. - //ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.absolute_delta_PUSCH = 0; - - // set FAPI parameters for UE, put them in the scheduled response and call - nr_ue_scheduled_response(&scheduled_response); - unsigned char *estimated_output_bit; unsigned char *test_input_bit; - unsigned int errors_bit = 0; + uint32_t errors_decoding = 0; uint32_t errors_scrambling = 0; + uint32_t is_frame_in_error = 0; test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - /////////////////////////phy_procedures_nr_ue_TX/////////////////////// - /////////// - - phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0); - - /////////// - //////////////////////////////////////////////////// - tx_offset = slot*frame_parms->samples_per_slot; - - txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], - frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); - - txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation - - + nr_scheduled_response_t scheduled_response; + fapi_nr_ul_config_request_t ul_config; printf("\n"); for (SNR = snr0; SNR < snr1; SNR += snr_step) { - n_errors = 0; - n_false_positive = 0; + printf("-------------------\n"); + printf("SNR %f\n", SNR); + printf("-------------------\n"); - //AWGN - sigma_dB = 10*log10(txlev_float)-SNR; - sigma = pow(10,sigma_dB/10); + is_frame_in_error = 0; + for (int frame = 0; frame < number_of_frames; frame++) { - for (trial = 0; trial < n_trials; trial++) { + UE_proc.nr_tti_tx = slot; + UE_proc.frame_tx = frame; - errors_scrambling = 0; - errors_bit = 0; - - for (i=0; inb_antennas_rx; ap++) { - // [hna] doesn't work with noise in case of mod_order = 6 - ((short*) gNB->common_vars.rxdata[ap])[2*i] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)])+ (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point - ((short*) gNB->common_vars.rxdata[ap])[2*i+1] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1])+ (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); - } - } + // --------- setting parameters for gNB -------- + /* + rel15_ul->rnti = n_rnti; + rel15_ul->ulsch_pdu_rel15.start_rb = start_rb; + rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb; + rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol; + rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = nb_re_dmrs; + rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs; + rel15_ul->ulsch_pdu_rel15.Qm = mod_order; + rel15_ul->ulsch_pdu_rel15.mcs = Imcs; + rel15_ul->ulsch_pdu_rel15.rv = 0; + rel15_ul->ulsch_pdu_rel15.ndi = 0; + rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers; + rel15_ul->ulsch_pdu_rel15.R = code_rate; + /////////////////////////////////////////////////// + */ + UL_tti_req->SFN = frame; + UL_tti_req->Slot = slot; + UL_tti_req->n_pdus = 1; + UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); - phy_procedures_gNB_common_RX(gNB, &gNB_proc); - - phy_procedures_gNB_uespec_RX(gNB, &gNB_proc, rel15_ul->ulsch_pdu_rel15.start_symbol, rel15_ul->ulsch_pdu_rel15.start_symbol + rel15_ul->ulsch_pdu_rel15.number_symbols); + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = n_rnti; + pusch_pdu->mcs_index = Imcs; + pusch_pdu->mcs_table = 0; + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = 0; + pusch_pdu->nrOfLayers = 1; + pusch_pdu->ul_dmrs_symb_pos = 1; + pusch_pdu->dmrs_config_type = 0; + pusch_pdu->ul_dmrs_scrambling_id = 0; + pusch_pdu->scid = 0; + pusch_pdu->resource_alloc = 1; + pusch_pdu->rb_start = start_rb; + pusch_pdu->rb_size = nb_rb; + pusch_pdu->vrb_to_prb_mapping = 0; + pusch_pdu->frequency_hopping = 0; + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + pusch_pdu->start_symbol_index = start_symbol; + pusch_pdu->nr_of_symbols = nb_symb_sch; + pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + nb_re_dmrs*length_dmrs, + 0, + pusch_pdu->nrOfLayers = 1); + pusch_pdu->pusch_data.num_cb = 0; - //---------------------------------------------------------- - //---------------------- count errors ---------------------- - //---------------------------------------------------------- + // --------- setting parameters for UE -------- - for (i = 0; i < available_bits; i++) { - - if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) || - ((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0))) - { - if(errors_scrambling == 0) { - printf("\n"); - printf("First bit in error in unscrambling = %d\n",i); + scheduled_response.module_id = 0; + scheduled_response.CC_id = 0; + scheduled_response.frame = frame; + scheduled_response.slot = slot; + scheduled_response.dl_config = NULL; + scheduled_response.ul_config = &ul_config; + scheduled_response.dl_config = NULL; + + ul_config.sfn_slot = slot; + 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].ulsch_config_pdu.rnti = n_rnti; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = Imcs; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = 0; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers; + ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid; + //there are plenty of other parameters that we don't seem to be using for now. e.g. + //ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.absolute_delta_PUSCH = 0; + + // set FAPI parameters for UE, put them in the scheduled response and call + nr_ue_scheduled_response(&scheduled_response); + + /////////////////////////phy_procedures_nr_ue_TX/////////////////////// + /////////// + + phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0); + + //LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_length_complex_samples,1,1); + + /////////// + //////////////////////////////////////////////////// + tx_offset = slot*frame_parms->samples_per_slot; + + txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + + txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation + + n_errors = 0; + n_false_positive = 0; + + //AWGN + sigma_dB = 10*log10(txlev_float)-SNR; + sigma = pow(10,sigma_dB/10); + + for (trial = 0; trial < n_trials; trial++) { + + errors_scrambling = 0; + errors_decoding = 0; + + //---------------------------------------------------------- + //------------------------ add noise ----------------------- + //---------------------------------------------------------- + for (i=0; inb_antennas_rx; ap++) { + ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point + ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); + } + } + //////////////////////////////////////////////////////////// + + //---------------------------------------------------------- + //------------------- gNB phy procedures ------------------- + //---------------------------------------------------------- + phy_procedures_gNB_common_RX(gNB, frame, slot); + + //LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],frame_length_complex_samples_no_prefix,1,1); + + phy_procedures_gNB_uespec_RX(gNB, frame, slot); + //////////////////////////////////////////////////////////// + + //---------------------------------------------------------- + //----------------- count and print errors ----------------- + //---------------------------------------------------------- + + for (i = 0; i < available_bits; i++) { + + if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) || + ((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0))) + { + if(errors_scrambling == 0) + printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i); + errors_scrambling++; } - errors_scrambling++; } - } - - for (i = 0; i < TBS; i++) { - - estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7); - test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments - - if (estimated_output_bit[i] != test_input_bit[i]) { - if(errors_bit == 0) - printf("First bit in error in decoding = %d\n",i); - errors_bit++; + if (errors_scrambling > 0) { + printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %d\n" "\x1B[0m", frame, trial, errors_scrambling); } - - } - //////////////////////////////////////////////////////////// + for (i = 0; i < TBS; i++) { - if (errors_scrambling > 0) { - if (n_trials == 1) - printf("errors_scrambling = %d (trial %d)\n", errors_scrambling, trial); - } + estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7); + test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7); - if (errors_bit > 0) { - n_false_positive++; - if (n_trials == 1) - printf("errors_bit = %d (trial %d)\n", errors_bit, trial); - } - printf("\n"); - } // [hna] for (trial = 0; trial < n_trials; trial++) - - printf("*****************************************\n"); - printf("SNR %f, (false positive %f)\n", SNR, - (float) n_false_positive / (float) n_trials); - printf("*****************************************\n"); - printf("\n"); + if (estimated_output_bit[i] != test_input_bit[i]) { + if(errors_decoding == 0) + printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i); + errors_decoding++; + } + } - if (errors_bit == 0) { - printf("PUSCH test OK\n"); - printf("\n"); + if (errors_decoding > 0) { + is_frame_in_error = 1; + n_false_positive++; + printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding = %d\n" "\x1B[0m", frame, trial, errors_decoding); + } else { + is_frame_in_error = 0; + break; + } + //////////////////////////////////////////////////////////// + } // trial loop + + if (is_frame_in_error == 1) + break; + } // frame loop + + if(is_frame_in_error == 0 || number_of_frames==1) break; - } - printf("\n"); - } // [hna] for (SNR = snr0; SNR < snr1; SNR += snr_step) + } // SNR loop - - for (i = 0; i < 2; i++) { - - printf("----------------------\n"); - printf("freeing codeword %d\n", i); - printf("----------------------\n"); - - printf("gNB ulsch[0][%d]\n", i); // [hna] ulsch[0] is for RA - - free_gNB_ulsch(gNB->ulsch[0][i]); - - printf("gNB ulsch[%d][%d]\n",UE_id+1, i); - - free_gNB_ulsch(gNB->ulsch[UE_id+1][i]); // "+1" because first element in ulsch is for RA - - for (sf = 0; sf < 2; sf++) { - - printf("UE ulsch[%d][0][%d]\n", sf, i); - - if (UE->ulsch[sf][0][i]) - free_nr_ue_ulsch(UE->ulsch[sf][0][i]); - } - + if(is_frame_in_error == 0) { printf("\n"); + printf("*************\n"); + printf("PUSCH test OK\n"); + printf("*************\n"); } + printf("\n"); + + free(test_input_bit); + free(estimated_output_bit); + if (output_fd) fclose(output_fd); diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c index fa243d1eb0..a93f0d48f3 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c @@ -119,7 +119,7 @@ void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync){} -uint32_t from_nrarfcn(int nr_bandP, uint32_t dl_nrarfcn) { return(0);} +uint64_t from_nrarfcn(int nr_bandP, uint32_t dl_nrarfcn) { return(0);} int32_t get_uldl_offset(int nr_bandP) { return(0);} diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index f056d51b5d..41d8551e75 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -30,11 +30,32 @@ #include "sim.h" #include "scm_corrmat.h" #include "common/utils/LOG/log.h" +#include "common/config/config_userapi.h" +#include "common/utils/telnetsrv/telnetsrv.h" +#include "common/utils/load_module_shlib.h" + + //#define DEBUG_CH #include "assertions.h" extern void print_shorts(char *s,__m128i *x); +static mapping channelmod_names[] = { + CHANNELMOD_MAP_INIT +}; + +static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static telnetshell_cmddef_t channelmod_cmdarray[] = { + {"show","",channelmod_show_cmd}, + {"","",NULL}, +}; + +static telnetshell_vardef_t channelmod_vardef[] = { + {"",0,NULL} +}; + +static double snr_dB=25; +static double sinr_dB=0; void fill_channel_desc(channel_desc_t *chan_desc, uint8_t nb_tx, @@ -43,7 +64,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, uint8_t channel_length, double *amps, double *delays, - struct complex** R_sqrt, + struct complex **R_sqrt, double Td, double sampling_rate, double channel_bandwidth, @@ -53,30 +74,27 @@ void fill_channel_desc(channel_desc_t *chan_desc, double max_Doppler, int32_t channel_offset, double path_loss_dB, - uint8_t random_aoa) -{ - - + uint8_t random_aoa) { uint16_t i,j; double delta_tau; - LOG_I(OCM,"[CHANNEL] Getting new channel descriptor, nb_tx %d, nb_rx %d, nb_taps %d, channel_length %d\n", - nb_tx,nb_rx,nb_taps,channel_length); - + nb_tx,nb_rx,nb_taps,channel_length); chan_desc->nb_tx = nb_tx; chan_desc->nb_rx = nb_rx; chan_desc->nb_taps = nb_taps; chan_desc->channel_length = channel_length; chan_desc->amps = amps; LOG_D(OCM,"[CHANNEL] Doing delays ...\n"); + if (delays==NULL) { - chan_desc->delays = (double*) malloc(nb_taps*sizeof(double)); + chan_desc->delays = (double *) malloc(nb_taps*sizeof(double)); delta_tau = Td/nb_taps; + for (i=0; idelays[i] = ((double)i)*delta_tau; - } - else - chan_desc->delays = delays; + } else + chan_desc->delays = delays; + chan_desc->Td = Td; chan_desc->sampling_rate = sampling_rate; chan_desc->channel_bandwidth = channel_bandwidth; @@ -89,43 +107,46 @@ void fill_channel_desc(channel_desc_t *chan_desc, chan_desc->first_run = 1; chan_desc->ip = 0.0; chan_desc->max_Doppler = max_Doppler; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(nb_taps*sizeof(struct complex*)); - + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(nb_taps*sizeof(struct complex *)); LOG_D(OCM,"[CHANNEL] Filling ch \n"); for (i = 0; ich[i] = (struct complex*) malloc(channel_length * sizeof(struct complex)); + chan_desc->ch[i] = (struct complex *) malloc(channel_length * sizeof(struct complex)); for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); // allocate for up to 100 RBs, 12 samples per RB + chan_desc->chF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); // allocate for up to 100 RBs, 12 samples per RB LOG_D(OCM,"[CHANNEL] Filling a (nb_taps %d)\n",nb_taps); + for (i = 0; ia[i],nb_tx*nb_rx * sizeof(struct complex)); - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); } LOG_D(OCM,"[CHANNEL] Doing R_sqrt ...\n"); + if (R_sqrt == NULL) { - chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); + chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *)); + for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); + chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; chan_desc->R_sqrt[i][j].y = 0.0; } } - } - else { - chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); + } else { + chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *)); + for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); - //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; - /* all chan_desc share the same R_sqrt, coming from caller */ - chan_desc->R_sqrt[i] = R_sqrt[0]; - } + //chan_desc->R_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); + //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; + /* all chan_desc share the same R_sqrt, coming from caller */ + chan_desc->R_sqrt[i] = R_sqrt[0]; + } } for (i = 0; iricean_factor); - for (i=0;inb_taps;i++) + + for (i=0; inb_taps; i++) LOG_D(OCM,"[CHANNEL] tap %d: amp %f, delay %f\n",i,chan_desc->amps[i],chan_desc->delays[i]); chan_desc->nb_paths=10; - reset_meas(&chan_desc->random_channel); reset_meas(&chan_desc->interp_time); reset_meas(&chan_desc->interp_freq); reset_meas(&chan_desc->convolution); - } double mbsfn_delays[] = {0,.03,.15,.31,.37,1.09,12.490,12.52,12.64,12.80,12.86,13.58,27.49,27.52,27.64,27.80,27.86,28.58}; @@ -162,7 +182,7 @@ double eva_amps_dB[] = {0.0,-1.5,-1.4,-3.6,-0.6,-9.1,-7.0,-12.0,-16.9}; double etu_delays[] = { 0,.05,.12,.2,.23,.5,1.6,2.3,5.0}; double etu_amps_dB[] = {-1.0,-1.0,-1.0,0.0,0.0,0.0,-3.0,-5.0,-7.0}; -double default_amps_lin[] = {0.3868472 , 0.3094778 , 0.1547389 , 0.0773694 , 0.0386847 , 0.0193424 , 0.0096712 , 0.0038685}; +double default_amps_lin[] = {0.3868472, 0.3094778, 0.1547389, 0.0773694, 0.0386847, 0.0193424, 0.0096712, 0.0038685}; double default_amp_lin[] = {1}; double ts_shift_delays[] = {0, 1/7.68}; @@ -170,9 +190,10 @@ double ts_shift_amps[] = {0, 1}; //correlation matrix for a 2x2 channel with full Tx correlation struct complex R_sqrt_22_corr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}, - {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}}; + {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}, + {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, + {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0} +}; struct complex *R_sqrt_22_corr[1] = {R_sqrt_22_corr_tap}; //correlation matrix for a fully correlated 2x1 channel (h1==h2) @@ -181,9 +202,10 @@ struct complex *R_sqrt_21_corr[1] = {R_sqrt_21_corr_tap}; //correlation matrix for a 2x2 channel with full Tx anti-correlation struct complex R_sqrt_22_anticorr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0}, - {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0}}; + {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0}, + {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, + {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0} +}; struct complex *R_sqrt_22_anticorr[1] = {R_sqrt_22_anticorr_tap}; //correlation matrix for a fully anti-correlated 2x1 channel (h1==-h2) @@ -195,9 +217,10 @@ struct complex **R_sqrt_ptr2; // full correlation matrix in vectorized form for 2x2 channel, where h1 is perfectly orthogonal to h2 struct complex R_sqrt_22_orthogonal_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.0,0.0}, - {0.0,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.70711,0.0}}; + {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.0,0.0}, + {0.0,0.0}, {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, + {0.0, 0.0}, {0.0,0.0}, {0.0, 0.0}, {0.70711,0.0} +}; struct complex *R_sqrt_22_orthogonal[1] = {R_sqrt_22_orthogonal_tap}; // full correlation matrix for TM4 to make orthogonal effective channel @@ -206,37 +229,43 @@ struct complex *R_sqrt_22_orthogonal[1] = {R_sqrt_22_orthogonal_tap}; struct complex R_sqrt_22_orth_eff_ch_TM4_prec_real_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {-0.70711,0.0}, - {0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}}; + {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {-0.70711,0.0}, + {0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, + {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0} +}; struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_real[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_real_tap}; struct complex R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap[16] = {{0.70711,0.0}, {0.0,0.0}, {0.0, -0.70711}, {0.0,0.0}, - {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.0,0.70711}, - {0.0,-0.70711}, {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {0.0,0.70711}, {0.0, 0.0}, {-0.70711,0.0}}; + {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.0,0.70711}, + {0.0,-0.70711}, {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, + {0.0, 0.0}, {0.0,0.70711}, {0.0, 0.0}, {-0.70711,0.0} +}; struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_imag[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap}; //Correlation matrix for EPA channel struct complex R_sqrt_22_EPA_low_tap[16] = {{1.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, - {0.0,0.0}, {1.0,0.0}, {0.0,0.0}, {0.0,0.0}, - {0.0,0.0}, {0.0,0.0}, {1.0,0.0}, {0.0,0.0}, - {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,0.0}}; + {0.0,0.0}, {1.0,0.0}, {0.0,0.0}, {0.0,0.0}, + {0.0,0.0}, {0.0,0.0}, {1.0,0.0}, {0.0,0.0}, + {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,0.0} +}; struct complex *R_sqrt_22_EPA_low[1] = {R_sqrt_22_EPA_low_tap}; -struct complex R_sqrt_22_EPA_high_tap[16] = {{0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0}, - {0.4500,0.0}, {0.7179,0.0}, {0.2821,0.0}, {0.4500,0.0}, - {0.4500,0.0}, {0.2821,0.0}, {0.7179,0.0}, {0.4500,0.0}, - {0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0}}; +struct complex R_sqrt_22_EPA_high_tap[16] = { + {0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0}, + {0.4500,0.0}, {0.7179,0.0}, {0.2821,0.0}, {0.4500,0.0}, + {0.4500,0.0}, {0.2821,0.0}, {0.7179,0.0}, {0.4500,0.0}, + {0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0} +}; struct complex *R_sqrt_22_EPA_high[1] = {R_sqrt_22_EPA_high_tap}; struct complex R_sqrt_22_EPA_medium_tap[16] = {{0.8375,0.0}, {0.5249,0.0}, {0.1286,0.0}, {0.0806,0.0}, - {0.5249,0.0}, {0.8375,0.0}, {0.0806,0.0}, {0.1286,0.0}, - {0.1286,0.0}, {0.0806,0.0}, {0.8375,0.0}, {0.5249,0.0}, - {0.0806,0.0}, {0.1286,0.0}, {0.5249,0.0}, {0.8375,0.0}}; + {0.5249,0.0}, {0.8375,0.0}, {0.0806,0.0}, {0.1286,0.0}, + {0.1286,0.0}, {0.0806,0.0}, {0.8375,0.0}, {0.5249,0.0}, + {0.0806,0.0}, {0.1286,0.0}, {0.5249,0.0}, {0.8375,0.0} +}; struct complex *R_sqrt_22_EPA_medium[1] = {R_sqrt_22_EPA_medium_tap}; @@ -250,15 +279,12 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, double channel_bandwidth, double forgetting_factor, int32_t channel_offset, - double path_loss_dB) -{ - + double path_loss_dB) { channel_desc_t *chan_desc = (channel_desc_t *)malloc(sizeof(channel_desc_t)); uint16_t i,j; double sum_amps; double aoa,ricean_factor,Td,maxDoppler; int channel_length,nb_taps; - chan_desc->nb_tx = nb_tx; chan_desc->nb_rx = nb_rx; chan_desc->sampling_rate = sampling_rate; @@ -268,424 +294,514 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->path_loss_dB = path_loss_dB; chan_desc->first_run = 1; chan_desc->ip = 0.0; - LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model); switch (channel_model) { - case SCM_A: - LOG_W(OCM,"channel model not yet supported\n"); - free(chan_desc); - return(NULL); - case SCM_B: - LOG_W(OCM,"channel model not yet supported\n"); - free(chan_desc); - return(NULL); - case SCM_C: - chan_desc->nb_taps = 18; - chan_desc->Td = 4.625; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = scm_c_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); + case SCM_A: + LOG_W(OCM,"channel model not yet supported\n"); + free(chan_desc); + return(NULL); - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } - else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; - } - else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; - } - else { - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); - } - } - break; - case SCM_D: - LOG_W(OCM,"This is not the real SCM-D model! It is just SCM-C with an additional Rice factor!\n"); - chan_desc->nb_taps = 18; - chan_desc->Td = 4.625; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = scm_c_delays; - chan_desc->ricean_factor = 0.1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); + case SCM_B: + LOG_W(OCM,"channel model not yet supported\n"); + free(chan_desc); + return(NULL); - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } - else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; - } - else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; - } - else { - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + case SCM_C: + chan_desc->nb_taps = 18; + chan_desc->Td = 4.625; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + sum_amps += chan_desc->amps[i]; } - } - break; - case EPA: - chan_desc->nb_taps = 7; - chan_desc->Td = .410; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = epa_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } - else { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); - } - } - break; - case EPA_low: - chan_desc->nb_taps = 7; - chan_desc->Td = .410; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = epa_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { - chan_desc->R_sqrt = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex**)); + for (i = 0; inb_taps; i++) - chan_desc->R_sqrt[i] = R_sqrt_22_EPA_low[0]; - } - else { - printf("Correlation matrices are implemented for 2 x 2 only"); - } - /*else { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); - } - }*/ - break; - case EPA_high: - chan_desc->nb_taps = 7; - chan_desc->Td = .410; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = epa_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { - chan_desc->R_sqrt = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex**)); + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = scm_c_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) - chan_desc->R_sqrt[i] = R_sqrt_22_EPA_high[0]; - } - else { - printf("Correlation matrices are implemented for 2 x 2 only"); - } - /*else { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + if (nb_tx==2 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; + } else if (nb_tx==2 && nb_rx==1) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0]; + } else if (nb_tx==1 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; + } else { + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } - }*/ - break; + + break; + + case SCM_D: + LOG_W(OCM,"This is not the real SCM-D model! It is just SCM-C with an additional Rice factor!\n"); + chan_desc->nb_taps = 18; + chan_desc->Td = 4.625; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = scm_c_delays; + chan_desc->ricean_factor = 0.1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + if (nb_tx==2 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; + } else if (nb_tx==2 && nb_rx==1) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0]; + } else if (nb_tx==1 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; + } else { + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + } + } + + break; + + case EPA: + chan_desc->nb_taps = 7; + chan_desc->Td = .410; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = epa_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; + } else { + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + } + + break; + + case EPA_low: + chan_desc->nb_taps = 7; + chan_desc->Td = .410; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = epa_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex **)); + + for (i = 0; inb_taps; i++) + chan_desc->R_sqrt[i] = R_sqrt_22_EPA_low[0]; + } else { + printf("Correlation matrices are implemented for 2 x 2 only"); + } + + /*else { + chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + }*/ + break; + + case EPA_high: + chan_desc->nb_taps = 7; + chan_desc->Td = .410; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = epa_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex **)); + + for (i = 0; inb_taps; i++) + chan_desc->R_sqrt[i] = R_sqrt_22_EPA_high[0]; + } else { + printf("Correlation matrices are implemented for 2 x 2 only"); + } + + /*else { + chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + }*/ + break; + case EPA_medium: - chan_desc->nb_taps = 7; - chan_desc->Td = .410; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = epa_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { - chan_desc->R_sqrt = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex**)); + chan_desc->nb_taps = 7; + chan_desc->Td = .410; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + for (i = 0; inb_taps; i++) - chan_desc->R_sqrt[i] = R_sqrt_22_EPA_medium[0]; - } else { - printf("Correlation matrices are implemented for 2 x 2 only"); - } - /*else { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); - } - }*/ - break; - case EVA: - chan_desc->nb_taps = 9; - chan_desc->Td = 2.51; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = eva_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } - else { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); - } - } - break; - case ETU: - chan_desc->nb_taps = 9; - chan_desc->Td = 5.0; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = etu_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } - else { - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); - } - } - break; - case MBSFN: - chan_desc->nb_taps = 18; - chan_desc->Td = 28.58; - chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); - sum_amps = 0; - chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); - sum_amps += chan_desc->amps[i]; - } - for (i = 0; inb_taps; i++) - chan_desc->amps[i] /= sum_amps; - chan_desc->delays = mbsfn_delays; - chan_desc->ricean_factor = 1; - chan_desc->aoa = 0; - chan_desc->random_aoa = 0; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) - chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); + chan_desc->amps[i] /= sum_amps; - chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex*)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); - } - break; - case Rayleigh8: + chan_desc->delays = epa_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex **)); + + for (i = 0; inb_taps; i++) + chan_desc->R_sqrt[i] = R_sqrt_22_EPA_medium[0]; + } else { + printf("Correlation matrices are implemented for 2 x 2 only"); + } + + /*else { + chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + }*/ + break; + + case EVA: + chan_desc->nb_taps = 9; + chan_desc->Td = 2.51; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = eva_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; + } else { + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + } + + break; + + case ETU: + chan_desc->nb_taps = 9; + chan_desc->Td = 5.0; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = etu_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; + } else { + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + } + + break; + + case MBSFN: + chan_desc->nb_taps = 18; + chan_desc->Td = 28.58; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); + + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + + chan_desc->delays = mbsfn_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *)); + chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *)); + + for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); + + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); + + chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex *)); + + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + + break; + + case Rayleigh8: nb_taps = 8; Td = 0.8; channel_length = (int)11+2*sampling_rate*Td; ricean_factor = 1; aoa = .03; maxDoppler = 0; - fill_channel_desc(chan_desc, nb_tx, nb_rx, @@ -706,88 +822,85 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, 0); break; - case Rice8: + case Rice8: nb_taps = 8; Td = 0.8; channel_length = (int)11+2*sampling_rate*Td; ricean_factor = 0.1; aoa = 0.7854; maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; - case Rayleigh1: + case Rayleigh1: nb_taps = 1; Td = 0; channel_length = 1; ricean_factor = 1; aoa = .03; maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - case Rayleigh1_800: + case Rayleigh1_800: nb_taps = 1; Td = 0; channel_length = 1; ricean_factor = 1; aoa = .03; maxDoppler = 800; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - case Rayleigh1_corr: + case Rayleigh1_corr: nb_taps = 1; Td = 0; channel_length = 1; @@ -797,33 +910,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, if ((nb_tx==2) && (nb_rx==1)) { R_sqrt_ptr2 = R_sqrt_21_corr; - } - else if ((nb_tx==2) && (nb_rx==2)) { + } else if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_corr; - } - else + } else R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - case Rayleigh1_anticorr: + case Rayleigh1_anticorr: nb_taps = 1; Td = 0; channel_length = 1; @@ -833,118 +944,111 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, if ((nb_tx==2) && (nb_rx==1)) { //check this R_sqrt_ptr2 = R_sqrt_21_anticorr; - } - else if ((nb_tx==2) && (nb_rx==2)) { + } else if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_anticorr; - } - else + } else R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - case Rice1: + case Rice1: nb_taps = 1; Td = 0; channel_length = 1; ricean_factor = 0.1; aoa = 0.7854; maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - case AWGN: + case AWGN: nb_taps = 1; Td = 0; channel_length = 1; ricean_factor = 0.0; aoa = 0.0; maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); printf("AWGN: ricean_factor %f\n",chan_desc->ricean_factor); - break; - case TS_SHIFT: + case TS_SHIFT: nb_taps = 2; Td = ts_shift_delays[1]; channel_length = 10; ricean_factor = 0.0; aoa = 0.0; maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - ts_shift_amps, - ts_shift_delays, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + ts_shift_amps, + ts_shift_delays, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); printf("TS_SHIFT: ricean_factor %f\n",chan_desc->ricean_factor); - break; - case Rice1_corr: + case Rice1_corr: nb_taps = 1; Td = 0; channel_length = 1; @@ -954,33 +1058,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, if ((nb_tx==2) && (nb_rx==1)) { R_sqrt_ptr2 = R_sqrt_21_corr; - } - else if ((nb_tx==2) && (nb_rx==2)) { + } else if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_corr; - } - else + } else R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; - case Rice1_anticorr: + case Rice1_anticorr: nb_taps = 1; Td = 0; channel_length = 1; @@ -990,33 +1092,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, if ((nb_tx==2) && (nb_rx==1)) { R_sqrt_ptr2 = R_sqrt_21_anticorr; - } - else if ((nb_tx==2) && (nb_rx==2)) { + } else if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_anticorr; - } - else + } else R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; - case Rayleigh1_orthogonal: + case Rayleigh1_orthogonal: nb_taps = 1; Td = 0; channel_length = 1; @@ -1024,33 +1124,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, aoa = 0.03; maxDoppler = 0; - if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_orthogonal; - } - else + } else R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - case Rayleigh1_orth_eff_ch_TM4_prec_real: + case Rayleigh1_orth_eff_ch_TM4_prec_real: nb_taps = 1; Td = 0; channel_length = 1; @@ -1058,33 +1156,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, aoa = 0.03; maxDoppler = 0; - if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; - } - else + } else R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; - case Rayleigh1_orth_eff_ch_TM4_prec_imag: + case Rayleigh1_orth_eff_ch_TM4_prec_imag: nb_taps = 1; Td = 0; channel_length = 1; @@ -1092,48 +1188,75 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, aoa = 0.03; maxDoppler = 0; - if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; - } - else + } else R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - case Rayleigh8_orth_eff_ch_TM4_prec_real: - - if ((nb_tx==2) && (nb_rx==2)) { + case Rayleigh8_orth_eff_ch_TM4_prec_real: + if ((nb_tx==2) && (nb_rx==2)) { R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; //R_sqrt_ptr2 = NULL; - } - else + } else R_sqrt_ptr2 = NULL; - nb_taps = 8; Td = 0.8; channel_length = (int)11+2*sampling_rate*Td; ricean_factor = 1; aoa = .03; maxDoppler = 0; + fill_channel_desc(chan_desc, + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; + + case Rayleigh8_orth_eff_ch_TM4_prec_imag: + nb_taps = 8; + Td = 0.8; + channel_length = (int)11+2*sampling_rate*Td; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; + + if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; + } else + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc, nb_tx, @@ -1153,77 +1276,40 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, channel_offset, path_loss_dB, 0); - break; - case Rayleigh8_orth_eff_ch_TM4_prec_imag: - nb_taps = 8; - Td = 0.8; - channel_length = (int)11+2*sampling_rate*Td; - ricean_factor = 1; - aoa = .03; - maxDoppler = 0; - - if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; - } - else - R_sqrt_ptr2 = NULL; - - fill_channel_desc(chan_desc, - nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; - - default: - LOG_W(OCM,"channel model not yet supported\n"); - free(chan_desc); - return(NULL); + default: + LOG_W(OCM,"channel model not yet supported\n"); + free(chan_desc); + return(NULL); } + LOG_D(OCM,"[CHANNEL] RF %f\n",chan_desc->ricean_factor); - for (i=0;inb_taps;i++) + + for (i=0; inb_taps; i++) LOG_D(OCM,"[CHANNEL] tap %d: amp %f, delay %f\n",i,chan_desc->amps[i],chan_desc->delays[i]); chan_desc->nb_paths = 10; - return(chan_desc); } -void free_channel_desc_scm(channel_desc_t * ch) { - // Must be made cleanly, a lot of leaks... - free(ch); +void free_channel_desc_scm(channel_desc_t *ch) { + // Must be made cleanly, a lot of leaks... + free(ch); } int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { - double s; int i,k,l,aarx,aatx; struct complex anew[NB_ANTENNAS_TX*NB_ANTENNAS_RX],acorr[NB_ANTENNAS_TX*NB_ANTENNAS_RX]; struct complex phase, alpha, beta; - AssertFatal(desc->nb_tx<=NB_ANTENNAS_TX && desc->nb_rx <= NB_ANTENNAS_RX, - "random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); - + "random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); start_meas(&desc->random_channel); - for (i=0;i<(int)desc->nb_taps;i++) { - for (aarx=0;aarxnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { + for (i=0; i<(int)desc->nb_taps; i++) { + for (aarx=0; aarxnb_rx; aarx++) { + for (aatx=0; aatxnb_tx; aatx++) { anew[aarx+(aatx*desc->nb_rx)].x = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); anew[aarx+(aatx*desc->nb_rx)].y = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); @@ -1237,10 +1323,10 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { // that we can safely assume plane wave propagation. phase.x = cos(M_PI*((aarx-aatx)*sin(desc->aoa))); phase.y = sin(M_PI*((aarx-aatx)*sin(desc->aoa))); - anew[aarx+(aatx*desc->nb_rx)].x += phase.x * sqrt(1.0-desc->ricean_factor); anew[aarx+(aatx*desc->nb_rx)].y += phase.y * sqrt(1.0-desc->ricean_factor); } + #ifdef DEBUG_CH printf("(%d,%d,%d) %f->(%f,%f) (%f,%f) phase (%f,%f)\n",aarx,aatx,i,desc->amps[i],anew[aarx+(aatx*desc->nb_rx)].x,anew[aarx+(aatx*desc->nb_rx)].y,desc->aoa,desc->ricean_factor,phase.x,phase.y); #endif @@ -1263,10 +1349,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { alpha.y = 0.0; beta.x = 0.0; beta.y = 0.0; - cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx, - (void*) &alpha, (void*) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, - (void*) anew, 1, (void*) &beta, (void*) acorr, 1); + (void *) &alpha, (void *) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, + (void *) anew, 1, (void *) &beta, (void *) acorr, 1); /* for (aarx=0;aarxnb_rx;aarx++) { @@ -1278,10 +1363,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { } */ - if (desc->first_run==1){ - cblas_zcopy(desc->nb_tx*desc->nb_rx, (void*) acorr, 1, (void*) desc->a[i], 1); - } - else { + if (desc->first_run==1) { + cblas_zcopy(desc->nb_tx*desc->nb_rx, (void *) acorr, 1, (void *) desc->a[i], 1); + } else { // a = alpha*acorr+beta*a // a = beta*a // a = a+alpha*acorr @@ -1289,9 +1373,8 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { alpha.y = 0; beta.x = sqrt(desc->forgetting_factor); beta.y = 0; - cblas_zscal(desc->nb_tx*desc->nb_rx, (void*) &beta, (void*) desc->a[i], 1); - cblas_zaxpy(desc->nb_tx*desc->nb_rx, (void*) &alpha, (void*) acorr, 1, (void*) desc->a[i], 1); - + cblas_zscal(desc->nb_tx*desc->nb_rx, (void *) &beta, (void *) desc->a[i], 1); + cblas_zaxpy(desc->nb_tx*desc->nb_rx, (void *) &alpha, (void *) acorr, 1, (void *) desc->a[i], 1); // desc->a[i][aarx+(aatx*desc->nb_rx)].x = (sqrt(desc->forgetting_factor)*desc->a[i][aarx+(aatx*desc->nb_rx)].x) + sqrt(1-desc->forgetting_factor)*anew.x; // desc->a[i][aarx+(aatx*desc->nb_rx)].y = (sqrt(desc->forgetting_factor)*desc->a[i][aarx+(aatx*desc->nb_rx)].y) + sqrt(1-desc->forgetting_factor)*anew.y; } @@ -1305,8 +1388,8 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { } } */ - } //nb_taps + stop_meas(&desc->random_channel); //memset((void *)desc->ch[aarx+(aatx*desc->nb_rx)],0,(int)(desc->channel_length)*sizeof(struct complex)); @@ -1320,7 +1403,6 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { desc->ch[aarx+(aatx*desc->nb_rx)][0].x = desc->a[0][aarx+(aatx*desc->nb_rx)].x; desc->ch[aarx+(aatx*desc->nb_rx)][0].y = desc->a[0][aarx+(aatx*desc->nb_rx)].y; } else { - for (k=0; k<(int)desc->channel_length; k++) { desc->ch[aarx+(aatx*desc->nb_rx)][k].x = 0.0; desc->ch[aarx+(aatx*desc->nb_rx)][k].y = 0.0; @@ -1335,18 +1417,18 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x; desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y; // printf("l %d : desc->ch.x %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x); - } //nb_taps #ifdef DEBUG_CH - k=0; - printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); + k=0; + printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); #endif - } - } //channel_length - } //aatx - } //aarx - stop_meas(&desc->interp_time); + } + } //channel_length + } //aatx + } //aarx + + stop_meas(&desc->interp_time); } if (desc->first_run==1) @@ -1355,69 +1437,103 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { return (0); } -double N_RB2sampling_rate(uint16_t N_RB) -{ +double N_RB2sampling_rate(uint16_t N_RB) { double sampling_rate; + switch (N_RB) { - case 6: - sampling_rate = 1.92; - break; + case 6: + sampling_rate = 1.92; + break; - case 25: - sampling_rate = 7.68; - break; + case 25: + sampling_rate = 7.68; + break; - case 50: - sampling_rate = 15.36; - break; + case 50: + sampling_rate = 15.36; + break; - case 100: - sampling_rate = 30.72; - break; + case 100: + sampling_rate = 30.72; + break; - default: - AssertFatal(1==0,"Unknown N_PRB %d",N_RB); + default: + AssertFatal(1==0,"Unknown N_PRB %d",N_RB); } return(sampling_rate); } -double N_RB2channel_bandwidth(uint16_t N_RB) -{ +double N_RB2channel_bandwidth(uint16_t N_RB) { double channel_bandwidth; + switch (N_RB) { - case 6: - channel_bandwidth = 1.25; - break; + case 6: + channel_bandwidth = 1.25; + break; - case 25: - channel_bandwidth = 5.00; - break; + case 25: + channel_bandwidth = 5.00; + break; - case 50: - channel_bandwidth = 10.00; - break; + case 50: + channel_bandwidth = 10.00; + break; - case 100: - channel_bandwidth = 20.00; - break; + case 100: + channel_bandwidth = 20.00; + break; - default: - LOG_E(PHY,"Unknown N_PRB\n"); - return(-1); + default: + LOG_E(PHY,"Unknown N_PRB\n"); + return(-1); } + return(channel_bandwidth); } +static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { + for(int i=0; channelmod_names[i].name != NULL ; i++) { + prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i )); + } + + return 0; +} + +int modelid_fromname(char *modelname) { + int modelid=map_str_to_int(channelmod_names,modelname); + AssertFatal(modelid>0, + "random_channel.c: Error channel model %s unknown\n",modelname); + return modelid; +} + +double channelmod_get_snr_dB(void) { + return snr_dB; +} + +double channelmod_get_sinr_dB(void) { + return sinr_dB; +} + +void init_channelmod(void) { + paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC; + int ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),CHANNELMOD_SECTION); + AssertFatal(ret >= 0, "configuration couldn't be performed"); + /* look for telnet server, if it is loaded, add the channel modeling commands to it */ + add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); + + if (addcmd != NULL) { + addcmd("channelmod",channelmod_vardef,channelmod_cmdarray); + } +} + #ifdef RANDOM_CHANNEL_MAIN #define sampling_rate 5.0 #define Td 2.0 main(int argc,char **argv) { - double amps[8] = {.8,.2,.1,.04,.02,.01,.005}; struct complex ch[(int)(1+2*sampling_rate*Td)],phase; int i; - randominit(); phase.x = 1.0; phase.y = 0; diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 1d5c43232e..0bc5975d99 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -147,7 +147,7 @@ typedef struct { /// Rice factor??? /// Walls (penetration loss) /// Nodes in the scenario - node_desc_t* nodes; + node_desc_t *nodes; } scenario_desc_t; typedef enum { @@ -180,29 +180,66 @@ typedef enum { EPA_medium, EPA_high, } SCM_t; +#define CHANNELMOD_MAP_INIT \ + {"custom",custom},\ + {"SCM_A",SCM_A},\ + {"SCM_B",SCM_B},\ + {"SCM_C",SCM_C},\ + {"SCM_D",SCM_D},\ + {"EPA",EPA},\ + {"EVA",EVA},\ + {"ETU",ETU},\ + {"MBSFN",MBSFN},\ + {"Rayleigh8",Rayleigh8},\ + {"Rayleigh1",Rayleigh1},\ + {"Rayleigh1_800",Rayleigh1_800},\ + {"Rayleigh1_corr",Rayleigh1_corr},\ + {"Rayleigh1_anticorr",Rayleigh1_anticorr},\ + {"Rice8",Rice8},\ + {"Rice1",Rice1},\ + {"Rice1_corr",Rice1_corr},\ + {"Rice1_anticorr",Rice1_anticorr},\ + {"AWGN",AWGN},\ + {"Rayleigh1_orthogonal",Rayleigh1_orthogonal},\ + {"Rayleigh1_orth_eff_ch_TM4_prec_real",Rayleigh1_orth_eff_ch_TM4_prec_real},\ + {"Rayleigh1_orth_eff_ch_TM4_prec_imag",Rayleigh1_orth_eff_ch_TM4_prec_imag},\ + {"Rayleigh8_orth_eff_ch_TM4_prec_real",Rayleigh8_orth_eff_ch_TM4_prec_real},\ + {"Rayleigh8_orth_eff_ch_TM4_prec_imag",Rayleigh8_orth_eff_ch_TM4_prec_imag},\ + {"TS_SHIFT",TS_SHIFT},\ + {"EPA_low",EPA_low},\ + {"EPA_medium",EPA_medium},\ + {"EPA_high",EPA_high},\ + {NULL, -1} + +#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" +#define CHANNELMOD_SECTION "channelmod" +#define CHANNELMOD_PARAMS_DESC { \ + {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB , defdblval:25, TYPE_DOUBLE, 0},\ + {"sinr_dB", NULL , 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\ + } #include "platform_constants.h" typedef struct { - channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs]; - channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs]; - double r_re_DL[NUMBER_OF_UE_MAX][2][30720]; - double r_im_DL[NUMBER_OF_UE_MAX][2][30720]; - double r_re_UL[NUMBER_OF_eNB_MAX][2][30720]; - double r_im_UL[NUMBER_OF_eNB_MAX][2][30720]; - int RU_output_mask[NUMBER_OF_UE_MAX]; - int UE_output_mask[NUMBER_OF_RU_MAX]; - pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX]; - pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX]; - pthread_mutex_t subframe_mutex; - int subframe_ru_mask; - int subframe_UE_mask; - openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; - openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; - openair0_timestamp last_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; - openair0_timestamp last_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; - double ru_amp[NUMBER_OF_RU_MAX]; - pthread_t rfsim_thread; + channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs]; + channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs]; + double r_re_DL[NUMBER_OF_UE_MAX][2][30720]; + double r_im_DL[NUMBER_OF_UE_MAX][2][30720]; + double r_re_UL[NUMBER_OF_eNB_MAX][2][30720]; + double r_im_UL[NUMBER_OF_eNB_MAX][2][30720]; + int RU_output_mask[NUMBER_OF_UE_MAX]; + int UE_output_mask[NUMBER_OF_RU_MAX]; + pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX]; + pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX]; + pthread_mutex_t subframe_mutex; + int subframe_ru_mask; + int subframe_UE_mask; + openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; + openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; + openair0_timestamp last_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs]; + openair0_timestamp last_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs]; + double ru_amp[NUMBER_OF_RU_MAX]; + pthread_t rfsim_thread; } sim_t; @@ -395,23 +432,40 @@ void multipath_tv_channel(channel_desc_t *desc, /**@} */ /**@} */ +void rxAddInput( struct complex16 *input_sig, + struct complex16 *after_channel_sig, + int rxAnt, + channel_desc_t *channelDesc, + int nbSamples, + uint64_t TS, + uint32_t CirSize + ); + +int modelid_fromname(char *modelname); +double channelmod_get_snr_dB(void); +double channelmod_get_sinr_dB(void); +void init_channelmod(void) ; + double N_RB2sampling_rate(uint16_t N_RB); double N_RB2channel_bandwidth(uint16_t N_RB); -//#include "targets/RT/USER/rfsim.h" +#include "targets/RT/USER/rfsim.h" void do_DL_sig(sim_t *sim, uint16_t subframe, uint32_t offset, uint32_t length, - uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *ue_frame_parms, + uint8_t abstraction_flag, + LTE_DL_FRAME_PARMS *ue_frame_parms, uint8_t UE_id, int CC_id); void do_UL_sig(sim_t *sim, - uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms, - uint32_t frame,int ru_id,uint8_t CC_id); + uint16_t subframe, + uint8_t abstraction_flag, + LTE_DL_FRAME_PARMS *frame_parms, + uint32_t frame, + int ru_id, + uint8_t CC_id); #endif - - diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 4f81c22fb0..054f3f3734 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -133,7 +133,7 @@ typedef struct gtpv1u_enb_data_forwarding_req_s { typedef struct gtpv1u_enb_data_forwarding_ind_s { uint32_t frame; uint8_t enb_flag; - uint32_t rb_id; + rb_id_t rb_id; uint32_t muip; uint32_t confirmp; uint32_t sdu_size; @@ -155,7 +155,7 @@ typedef struct gtpv1u_enb_end_marker_req_s { typedef struct gtpv1u_enb_end_marker_ind_s { uint32_t frame; uint8_t enb_flag; - uint32_t rb_id; + rb_id_t rb_id; uint32_t muip; uint32_t confirmp; uint32_t sdu_size; diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index 8a58d07d65..4a0a6027bc 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -20,15 +20,14 @@ */ #ifndef __MAC_RRC_PRIMITIVES_H__ -# define __MAC_RRC_PRIMITIVES_H__ - - +#define __MAC_RRC_PRIMITIVES_H__ #ifndef OPENAIR2_IN #include "LAYER2/RLC/rlc.h" #endif #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" +#include "openair2/RRC/LTE/rrc_defs.h" #include "LTE_RadioResourceConfigCommonSIB.h" #include "LTE_RadioResourceConfigDedicated.h" @@ -398,5 +397,3 @@ typedef struct { #define REMOVE_LC 1 #endif - - diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h index c90490b0fd..1551e4283f 100644 --- a/openair2/COMMON/pdcp_messages_types.h +++ b/openair2/COMMON/pdcp_messages_types.h @@ -40,7 +40,7 @@ typedef struct RrcDcchDataReq_s { uint32_t frame; uint8_t enb_flag; - uint32_t rb_id; + rb_id_t rb_id; uint32_t muip; uint32_t confirmp; uint32_t sdu_size; diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index aab2afff82..1784098b79 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -98,7 +98,9 @@ #endif #define NUMBER_OF_NR_DLSCH_MAX 2//16 -#define NUMBER_OF_NR_ULSCH_MAX 16 +#define NUMBER_OF_NR_ULSCH_MAX 2//16 +#define NUMBER_OF_NR_SR_MAX 16 + #define MAX_MANAGED_ENB_PER_MOBILE 2 #define MAX_MANAGED_GNB_PER_MOBILE 2 diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 977f44a310..2555be081a 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -71,8 +71,8 @@ typedef uint8_t slice_id_t; typedef uint8_t eNB_index_t; typedef uint16_t ue_id_t; typedef int16_t smodule_id_t; -typedef uint16_t rb_id_t; -typedef uint16_t srb_id_t; +typedef long rb_id_t; +typedef long srb_id_t; typedef boolean_t MBMS_flag_t; #define MBMS_FLAG_NO FALSE @@ -302,5 +302,12 @@ typedef struct protocol_ctxt_s { #define CHECK_CTXT_ARGS(CTXT_Pp) #define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) +#ifdef __cplusplus +extern "C" +{ +#endif void exit_function(const char *file, const char *function, const int line, const char *s); +#ifdef __cplusplus +} +#endif #endif diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index ad145f09f6..2948d59b02 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -274,6 +274,7 @@ typedef struct RrcConfigurationReq_s { long *pdsch_maxNumRepetitionCEmodeB_r13 [MAX_NUM_CCs]; long *pusch_maxNumRepetitionCEmodeA_r13 [MAX_NUM_CCs]; long *pusch_maxNumRepetitionCEmodeB_r13 [MAX_NUM_CCs]; + long *pusch_repetitionLevelCEmodeA_r13 [MAX_NUM_CCs]; long *pusch_HoppingOffset_v1310 [MAX_NUM_CCs]; //SIB18 @@ -400,6 +401,7 @@ typedef struct NRRrcConfigurationReq_s { uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; NR_ServingCellConfigCommon_t *scc; int ssb_SubcarrierOffset; + int pdsch_AntennaPorts; } gNB_RrcConfigurationReq; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 3c925a0410..996c23229e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -55,11 +55,8 @@ #include "RRC_config_tools.h" #include "enb_paramdef.h" #include "proto_agent.h" +#include "executables/thread-common.h" -extern void set_parallel_conf(char *parallel_conf); -extern void set_worker_conf(char *worker_conf); -//extern PARALLEL_CONF_t get_thread_parallel_conf(void); -//extern WORKER_CONF_t get_thread_worker_conf(void); extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw); extern char *parallel_config; diff --git a/openair2/ENB_APP/enb_config_eMTC.c b/openair2/ENB_APP/enb_config_eMTC.c index 45d67120bd..cfd057bad8 100644 --- a/openair2/ENB_APP/enb_config_eMTC.c +++ b/openair2/ENB_APP/enb_config_eMTC.c @@ -859,6 +859,21 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in config_fname); } + RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = CALLOC(1, sizeof(long)); + if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l1")) { + *RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 0; + } else if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l2")) { + *RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 1; + } else if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l3")) { + *RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 2; + } else if (!strcmp(eMTCconfig->pusch_repetitionLevelCEmodeA_r13, "l4")) { + *RRC_CONFIGURATION_REQ(msg_p).pusch_repetitionLevelCEmodeA_r13[cc_idx] = 3; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, pusch_repetitionLevelCEmodeA_r13 unknown value!\n", + config_fname); + } + char rachCELevelInfoListPath[MAX_OPTNAME_SIZE * 2]; config_getlist(&rachcelevellist, NULL, 0, brparamspath); RRC_CONFIGURATION_REQ (msg_p).rach_CE_LevelInfoList_r13_size[cc_idx] = rachcelevellist.numelt; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 165675ab12..0fedc04abd 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -93,6 +93,7 @@ typedef enum { #define CONFIG_STRING_RU_SF_EXTENSION "sf_extension" #define CONFIG_STRING_RU_END_OF_BURST_DELAY "end_of_burst_delay" #define CONFIG_STRING_RU_OTA_SYNC_ENABLE "ota_sync_enabled" +#define CONFIG_STRING_RU_BF_WEIGHTS_LIST "bf_weights" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -118,23 +119,22 @@ typedef enum { #define RU_SF_EXTENSION_IDX 21 #define RU_END_OF_BURST_DELAY_IDX 22 #define RU_OTA_SYNC_ENABLE_IDX 23 - - +#define RU_BF_WEIGHTS_LIST_IDX 24 /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------*/ #define RUPARAMS_DESC { \ - {CONFIG_STRING_RU_LOCAL_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_LOCAL_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_REMOTE_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_LOCAL_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_LOCAL_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_REMOTE_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_LOCAL_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_REMOTE_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_LOCAL_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_REMOTE_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_TRANSPORT_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"udp_if5", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_LOCAL_RF, NULL, 0, strptr:NULL, defstrval:"yes", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_TRANSPORT_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"udp_if5", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_LOCAL_RF, NULL, 0, strptr:NULL, defstrval:"yes", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_NB_TX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_NB_RX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_MAX_RS_EPRE, NULL, 0, iptr:NULL, defintval:-29, TYPE_INT, 0}, \ @@ -143,13 +143,14 @@ typedef enum { {CONFIG_STRING_RU_ENB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_IS_SLAVE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ + {CONFIG_STRING_RU_IS_SLAVE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"type=b200", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_SF_EXTENSION, NULL, 0, uptr:NULL, defuintval:312, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_END_OF_BURST_DELAY, NULL, 0, uptr:NULL, defuintval:400, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_SF_EXTENSION, NULL, 0, uptr:NULL, defuintval:312, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_END_OF_BURST_DELAY, NULL, 0, uptr:NULL, defuintval:400, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_BF_WEIGHTS_LIST, NULL, 0, iptr:NULL, defintarrayval:DEFBFW, TYPE_INTARRAY, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -245,7 +246,7 @@ typedef enum { #define ENB_ENABLE_X2 17 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} -#define ENBPARAMS_CHECK { \ +#define ENBPARAMS_CHECK { \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ @@ -394,6 +395,7 @@ typedef enum { #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" +#define ENB_CONFIG_STRING_PUSCH_REPETITION_LEVEL_CE_MODE_A_R13 "pusch_repetitionLevelCEmodeA_r13" #define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" @@ -536,289 +538,288 @@ typedef struct ccparams_lte_s { int32_t srb1_max_retx_threshold; } ccparams_lte_t; -#define CCPARAMS_CHECK { \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ - { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ - { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \ - { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \ - { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \ - { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} , \ - { .s5= {NULL }} \ - } -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* component carriers configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CCPARAMS_CHECK { \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} ,\ + { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} ,\ + { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} ,\ + { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} ,\ + { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} ,\ + { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} ,\ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } , \ + { .s5 = { NULL } } \ +} -#define CCPARAMS_DESC(ccparams) { \ - {ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&ccparams.frame_type, defstrval:"FDD", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&ccparams.tdd_config, defintval:3, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:&ccparams.tdd_config_s, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PREFIX_TYPE, NULL, 0, strptr:&ccparams.prefix_type, defstrval:"NORMAL", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PBCH_REPETITION, NULL, 0, strptr:&ccparams.pbch_repetition, defstrval:"FALSE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:&ccparams.eutra_band, defintval:7, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:(int64_t *)&ccparams.downlink_frequency, defint64val:2680000000, TYPE_UINT64, 0}, \ - {ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:&ccparams.uplink_frequency_offset, defintval:-120000000, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:&ccparams.Nid_cell, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:&ccparams.N_RB_DL, defintval:25, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_CELL_MBSFN, NULL, 0, iptr:&ccparams.Nid_cell_mbsfn, defintval:0, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_NB_ANT_PORTS, NULL, 0, iptr:&ccparams.nb_antenna_ports, defintval:1, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PRACH_ROOT, NULL, 0, iptr:&ccparams.prach_root, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PRACH_CONFIG_INDEX, NULL, 0, iptr:&ccparams.prach_config_index, defintval:0, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_PRACH_HIGH_SPEED, NULL, 0, strptr:&ccparams.prach_high_speed, defstrval:"DISABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION, NULL, 0, iptr:&ccparams.prach_zero_correlation, defintval:1, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PRACH_FREQ_OFFSET, NULL, 0, iptr:&ccparams.prach_freq_offset, defintval:2, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT, NULL, 0, iptr:&ccparams.pucch_delta_shift, defintval:1, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PUCCH_NRB_CQI, NULL, 0, iptr:&ccparams.pucch_nRB_CQI, defintval:1, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PUCCH_NCS_AN, NULL, 0, iptr:&ccparams.pucch_nCS_AN, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PUCCH_N1_AN, NULL, 0, iptr:&ccparams.pucch_n1_AN, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PDSCH_RS_EPRE, NULL, 0, iptr:&ccparams.pdsch_referenceSignalPower, defintval:-29, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_PDSCH_PB, NULL, 0, iptr:&ccparams.pdsch_p_b, defintval:0, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_PUSCH_N_SB, NULL, 0, iptr:&ccparams.pusch_n_SB, defintval:1, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_PUSCH_HOPPINGMODE, NULL, 0, strptr:&ccparams.pusch_hoppingMode, defstrval:"interSubFrame", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET, NULL, 0, iptr:&ccparams.pusch_hoppingOffset, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PUSCH_ENABLE64QAM, NULL, 0, strptr:&ccparams.pusch_enable64QAM, defstrval:"DISABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN, NULL, 0, strptr:&ccparams.pusch_groupHoppingEnabled, defstrval:"ENABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT, NULL, 0, iptr:&ccparams.pusch_groupAssignment, defintval:0, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN, NULL, 0, strptr:&ccparams.pusch_sequenceHoppingEnabled, defstrval:"DISABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUSCH_NDMRS1, NULL, 0, iptr:&ccparams.pusch_nDMRS1, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PHICH_DURATION, NULL, 0, strptr:&ccparams.phich_duration, defstrval:"NORMAL", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PHICH_RESOURCE, NULL, 0, strptr:&ccparams.phich_resource, defstrval:"ONESIXTH", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_SRS_ENABLE, NULL, 0, strptr:&ccparams.srs_enable, defstrval:"DISABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG, NULL, 0, iptr:&ccparams.srs_BandwidthConfig, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG, NULL, 0, iptr:&ccparams.srs_SubframeConfig, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG, NULL, 0, strptr:&ccparams.srs_ackNackST, defstrval:"DISABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_SRS_MAXUPPTS, NULL, 0, strptr:&ccparams.srs_MaxUpPts, defstrval:"DISABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUSCH_PO_NOMINAL, NULL, 0, iptr:&ccparams.pusch_p0_Nominal, defintval:-90, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_PUSCH_ALPHA, NULL, 0, strptr:&ccparams.pusch_alpha, defstrval:"AL1", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUCCH_PO_NOMINAL, NULL, 0, iptr:&ccparams.pucch_p0_Nominal, defintval:-96, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE, NULL, 0, iptr:&ccparams.msg3_delta_Preamble, defintval:6, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1, NULL, 0, strptr:&ccparams.pucch_deltaF_Format1, defstrval:"DELTAF2", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b, NULL, 0, strptr:&ccparams.pucch_deltaF_Format1b, defstrval:"deltaF3", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2, NULL, 0, strptr:&ccparams.pucch_deltaF_Format2, defstrval:"deltaF0", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A, NULL, 0, strptr:&ccparams.pucch_deltaF_Format2a, defstrval:"deltaF0", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B, NULL, 0, strptr:&ccparams.pucch_deltaF_Format2b, defstrval:"deltaF0", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES, NULL, 0, iptr:&ccparams.rach_numberOfRA_Preambles, defintval:4, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG, NULL, 0, strptr:&ccparams.rach_preamblesGroupAConfig, defstrval:"DISABLE", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA, NULL, 0, iptr:&ccparams.rach_sizeOfRA_PreamblesGroupA, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA, NULL, 0, iptr:&ccparams.rach_messageSizeGroupA, defintval:56, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB, NULL, 0, strptr:&ccparams.rach_messagePowerOffsetGroupB, defstrval:"minusinfinity", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP, NULL, 0, iptr:&ccparams.rach_powerRampingStep, defintval:4, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER, NULL, 0, iptr:&ccparams.rach_preambleInitialReceivedTargetPower, defintval:-100, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX, NULL, 0, iptr:&ccparams.rach_preambleTransMax, defintval:10, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE, NULL, 0, iptr:&ccparams.rach_raResponseWindowSize, defintval:10, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER, NULL, 0, iptr:&ccparams.rach_macContentionResolutionTimer, defintval:48, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX, NULL, 0, iptr:&ccparams.rach_maxHARQ_Msg3Tx, defintval:4, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE, NULL, 0, iptr:&ccparams.pcch_defaultPagingCycle, defintval:128, TYPE_INT, 0}, \ - {ENB_CONFIG_STRING_PCCH_NB, NULL, 0, strptr:&ccparams.pcch_nB, defstrval:"oneT", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DRX_CONFIG_PRESENT, NULL, 0, strptr:&ccparams.drx_Config_present, defstrval:"prNothing", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DRX_ONDURATIONTIMER, NULL, 0, strptr:&ccparams.drx_onDurationTimer, defstrval:"psf10", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DRX_INACTIVITYTIMER, NULL, 0, strptr:&ccparams.drx_InactivityTimer, defstrval:"psf10", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER, NULL, 0, strptr:&ccparams.drx_RetransmissionTimer, defstrval:"psf8", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT, NULL, 0, strptr:&ccparams.drx_longDrx_CycleStartOffset_present, defstrval:"prSf128", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET, NULL, 0, iptr:&ccparams.drx_longDrx_CycleStartOffset, defintval:0, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE, NULL, 0, strptr:&ccparams.drx_shortDrx_Cycle, defstrval:"sf32", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER, NULL, 0, iptr:&ccparams.drx_shortDrx_ShortCycleTimer, defintval:3, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF, NULL, 0, iptr:&ccparams.bcch_modificationPeriodCoeff, defintval:2, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UETIMERS_T300, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t300, defintval:1000, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UETIMERS_T301, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t301, defintval:1000, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UETIMERS_T310, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t310, defintval:1000, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UETIMERS_T311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t311, defintval:10000, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UETIMERS_N310, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n310, defintval:20, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UETIMERS_N311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n311, defintval:1, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ccparams.ue_TransmissionMode, defintval:1, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL, NULL, 0, strptr:&ccparams.mbms_dedicated_serving_cell, defstrval:"DISABLE", TYPE_STRING, 0} \ - } +/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* component carriers configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CCPARAMS_DESC(ccparams) { \ + {ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&ccparams.frame_type, defstrval:"FDD", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&ccparams.tdd_config, defintval:3, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:&ccparams.tdd_config_s, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PREFIX_TYPE, NULL, 0, strptr:&ccparams.prefix_type, defstrval:"NORMAL", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PBCH_REPETITION, NULL, 0, strptr:&ccparams.pbch_repetition, defstrval:"FALSE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:&ccparams.eutra_band, defintval:7, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:(int64_t *)&ccparams.downlink_frequency, defint64val:2680000000, TYPE_UINT64, 0}, \ + {ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:&ccparams.uplink_frequency_offset, defintval:-120000000, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:&ccparams.Nid_cell, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:&ccparams.N_RB_DL, defintval:25, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_CELL_MBSFN, NULL, 0, iptr:&ccparams.Nid_cell_mbsfn, defintval:0, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_NB_ANT_PORTS, NULL, 0, iptr:&ccparams.nb_antenna_ports, defintval:1, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PRACH_ROOT, NULL, 0, iptr:&ccparams.prach_root, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PRACH_CONFIG_INDEX, NULL, 0, iptr:&ccparams.prach_config_index, defintval:0, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_PRACH_HIGH_SPEED, NULL, 0, strptr:&ccparams.prach_high_speed, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION, NULL, 0, iptr:&ccparams.prach_zero_correlation, defintval:1, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PRACH_FREQ_OFFSET, NULL, 0, iptr:&ccparams.prach_freq_offset, defintval:2, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT, NULL, 0, iptr:&ccparams.pucch_delta_shift, defintval:1, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PUCCH_NRB_CQI, NULL, 0, iptr:&ccparams.pucch_nRB_CQI, defintval:1, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PUCCH_NCS_AN, NULL, 0, iptr:&ccparams.pucch_nCS_AN, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PUCCH_N1_AN, NULL, 0, iptr:&ccparams.pucch_n1_AN, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PDSCH_RS_EPRE, NULL, 0, iptr:&ccparams.pdsch_referenceSignalPower, defintval:-29, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_PDSCH_PB, NULL, 0, iptr:&ccparams.pdsch_p_b, defintval:0, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_PUSCH_N_SB, NULL, 0, iptr:&ccparams.pusch_n_SB, defintval:1, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_PUSCH_HOPPINGMODE, NULL, 0, strptr:&ccparams.pusch_hoppingMode, defstrval:"interSubFrame", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET, NULL, 0, iptr:&ccparams.pusch_hoppingOffset, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PUSCH_ENABLE64QAM, NULL, 0, strptr:&ccparams.pusch_enable64QAM, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN, NULL, 0, strptr:&ccparams.pusch_groupHoppingEnabled, defstrval:"ENABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT, NULL, 0, iptr:&ccparams.pusch_groupAssignment, defintval:0, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN, NULL, 0, strptr:&ccparams.pusch_sequenceHoppingEnabled, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUSCH_NDMRS1, NULL, 0, iptr:&ccparams.pusch_nDMRS1, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PHICH_DURATION, NULL, 0, strptr:&ccparams.phich_duration, defstrval:"NORMAL", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PHICH_RESOURCE, NULL, 0, strptr:&ccparams.phich_resource, defstrval:"ONESIXTH", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_SRS_ENABLE, NULL, 0, strptr:&ccparams.srs_enable, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG, NULL, 0, iptr:&ccparams.srs_BandwidthConfig, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG, NULL, 0, iptr:&ccparams.srs_SubframeConfig, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG, NULL, 0, strptr:&ccparams.srs_ackNackST, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_SRS_MAXUPPTS, NULL, 0, strptr:&ccparams.srs_MaxUpPts, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUSCH_PO_NOMINAL, NULL, 0, iptr:&ccparams.pusch_p0_Nominal, defintval:-90, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_PUSCH_ALPHA, NULL, 0, strptr:&ccparams.pusch_alpha, defstrval:"AL1", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUCCH_PO_NOMINAL, NULL, 0, iptr:&ccparams.pucch_p0_Nominal, defintval:-96, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE, NULL, 0, iptr:&ccparams.msg3_delta_Preamble, defintval:6, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1, NULL, 0, strptr:&ccparams.pucch_deltaF_Format1, defstrval:"DELTAF2", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b, NULL, 0, strptr:&ccparams.pucch_deltaF_Format1b, defstrval:"deltaF3", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2, NULL, 0, strptr:&ccparams.pucch_deltaF_Format2, defstrval:"deltaF0", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A, NULL, 0, strptr:&ccparams.pucch_deltaF_Format2a, defstrval:"deltaF0", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B, NULL, 0, strptr:&ccparams.pucch_deltaF_Format2b, defstrval:"deltaF0", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES, NULL, 0, iptr:&ccparams.rach_numberOfRA_Preambles, defintval:4, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG, NULL, 0, strptr:&ccparams.rach_preamblesGroupAConfig, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA, NULL, 0, iptr:&ccparams.rach_sizeOfRA_PreamblesGroupA, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA, NULL, 0, iptr:&ccparams.rach_messageSizeGroupA, defintval:56, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB, NULL, 0, strptr:&ccparams.rach_messagePowerOffsetGroupB, defstrval:"minusinfinity", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP, NULL, 0, iptr:&ccparams.rach_powerRampingStep, defintval:4, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER, NULL, 0, iptr:&ccparams.rach_preambleInitialReceivedTargetPower, defintval:-100, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX, NULL, 0, iptr:&ccparams.rach_preambleTransMax, defintval:10, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE, NULL, 0, iptr:&ccparams.rach_raResponseWindowSize, defintval:10, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER, NULL, 0, iptr:&ccparams.rach_macContentionResolutionTimer, defintval:48, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX, NULL, 0, iptr:&ccparams.rach_maxHARQ_Msg3Tx, defintval:4, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE, NULL, 0, iptr:&ccparams.pcch_defaultPagingCycle, defintval:128, TYPE_INT, 0}, \ + {ENB_CONFIG_STRING_PCCH_NB, NULL, 0, strptr:&ccparams.pcch_nB, defstrval:"oneT", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DRX_CONFIG_PRESENT, NULL, 0, strptr:&ccparams.drx_Config_present, defstrval:"prNothing", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DRX_ONDURATIONTIMER, NULL, 0, strptr:&ccparams.drx_onDurationTimer, defstrval:"psf10", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DRX_INACTIVITYTIMER, NULL, 0, strptr:&ccparams.drx_InactivityTimer, defstrval:"psf10", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER, NULL, 0, strptr:&ccparams.drx_RetransmissionTimer, defstrval:"psf8", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT, NULL, 0, strptr:&ccparams.drx_longDrx_CycleStartOffset_present, defstrval:"prSf128", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET, NULL, 0, iptr:&ccparams.drx_longDrx_CycleStartOffset, defintval:0, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE, NULL, 0, strptr:&ccparams.drx_shortDrx_Cycle, defstrval:"sf32", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER, NULL, 0, iptr:&ccparams.drx_shortDrx_ShortCycleTimer, defintval:3, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF, NULL, 0, iptr:&ccparams.bcch_modificationPeriodCoeff, defintval:2, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UETIMERS_T300, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t300, defintval:1000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UETIMERS_T301, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t301, defintval:1000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UETIMERS_T310, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t310, defintval:1000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UETIMERS_T311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t311, defintval:10000, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UETIMERS_N310, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n310, defintval:20, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UETIMERS_N311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n311, defintval:1, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ccparams.ue_TransmissionMode, defintval:1, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL, NULL, 0, strptr:&ccparams.mbms_dedicated_serving_cell, defstrval:"DISABLE", TYPE_STRING, 0} \ +} - -#define ENB_CONFIG_FRAME_TYPE_IDX 0 -#define ENB_CONFIG_TDD_CONFIG_IDX 1 -#define ENB_CONFIG_TDD_CONFIG_S_IDX 2 -#define ENB_CONFIG_PREFIX_TYPE_IDX 3 -#define ENB_CONFIG_PBCH_REPETITION_IDX 4 -#define ENB_CONFIG_EUTRA_BAND_IDX 5 -#define ENB_CONFIG_DOWNLINK_FREQUENCY_IDX 6 -#define ENB_CONFIG_UPLINK_FREQUENCY_OFFSET_IDX 7 -#define ENB_CONFIG_NID_CELL_IDX 8 -#define ENB_CONFIG_N_RB_DL_IDX 9 -#define ENB_CONFIG_CELL_MBSFN_IDX 10 -#define ENB_CONFIG_NB_ANT_PORTS_IDX 11 -#define ENB_CONFIG_PRACH_ROOT_IDX 12 -#define ENB_CONFIG_PRACH_CONFIG_INDEX_IDX 13 -#define ENB_CONFIG_PRACH_HIGH_SPEED_IDX 14 -#define ENB_CONFIG_PRACH_ZERO_CORRELATION_IDX 15 -#define ENB_CONFIG_PRACH_FREQ_OFFSET_IDX 16 -#define ENB_CONFIG_PUCCH_DELTA_SHIFT_IDX 17 -#define ENB_CONFIG_PUCCH_NRB_CQI_IDX 18 -#define ENB_CONFIG_PUCCH_NCS_AN_IDX 19 -#define ENB_CONFIG_PUCCH_N1_AN_IDX 20 -#define ENB_CONFIG_PDSCH_RS_EPRE_IDX 21 -#define ENB_CONFIG_PDSCH_PB_IDX 22 -#define ENB_CONFIG_PUSCH_N_SB_IDX 23 -#define ENB_CONFIG_PUSCH_HOPPINGMODE_IDX 24 -#define ENB_CONFIG_PUSCH_HOPPINGOFFSET_IDX 25 -#define ENB_CONFIG_PUSCH_ENABLE64QAM_IDX 26 -#define ENB_CONFIG_PUSCH_GROUP_HOPPING_EN_IDX 27 -#define ENB_CONFIG_PUSCH_GROUP_ASSIGNMENT_IDX 28 -#define ENB_CONFIG_PUSCH_SEQUENCE_HOPPING_EN_IDX 29 -#define ENB_CONFIG_PUSCH_NDMRS1_IDX 30 -#define ENB_CONFIG_PHICH_DURATION_IDX 31 -#define ENB_CONFIG_PHICH_RESOURCE_IDX 32 -#define ENB_CONFIG_SRS_ENABLE_IDX 33 -#define ENB_CONFIG_SRS_BANDWIDTH_CONFIG_IDX 34 -#define ENB_CONFIG_SRS_SUBFRAME_CONFIG_IDX 35 -#define ENB_CONFIG_SRS_ACKNACKST_CONFIG_IDX 36 -#define ENB_CONFIG_SRS_MAXUPPTS_IDX 37 -#define ENB_CONFIG_PUSCH_PO_NOMINAL_IDX 38 -#define ENB_CONFIG_PUSCH_ALPHA_IDX 39 -#define ENB_CONFIG_PUCCH_PO_NOMINAL_IDX 40 -#define ENB_CONFIG_MSG3_DELTA_PREAMBLE_IDX 41 -#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1_IDX 42 -#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1b_IDX 43 -#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2_IDX 44 -#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2A_IDX 45 -#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2B_IDX 46 -#define ENB_CONFIG_RACH_NUM_RA_PREAMBLES_IDX 47 -#define ENB_CONFIG_RACH_PREAMBLESGROUPACONFIG_IDX 48 -#define ENB_CONFIG_RACH_SIZEOFRA_PREAMBLESGROUPA_IDX 49 -#define ENB_CONFIG_RACH_MESSAGESIZEGROUPA_IDX 50 -#define ENB_CONFIG_RACH_MESSAGEPOWEROFFSETGROUPB_IDX 51 -#define ENB_CONFIG_RACH_POWERRAMPINGSTEP_IDX 52 -#define ENB_CONFIG_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_IDX 53 -#define ENB_CONFIG_RACH_PREAMBLETRANSMAX_IDX 54 -#define ENB_CONFIG_RACH_RARESPONSEWINDOWSIZE_IDX 55 -#define ENB_CONFIG_RACH_MACCONTENTIONRESOLUTIONTIMER_IDX 56 -#define ENB_CONFIG_RACH_MAXHARQMSG3TX_IDX 57 -#define ENB_CONFIG_PCCH_DEFAULT_PAGING_CYCLE_IDX 58 -#define ENB_CONFIG_PCCH_NB_IDX 59 -#define ENB_CONFIG_STRING_DRX_CONFIG_PRESENT_IDX 60 -#define ENB_CONFIG_STRING_DRX_ONDURATIONTIMER_IDX 61 -#define ENB_CONFIG_STRING_DRX_INACTIVITYTIMER_IDX 62 -#define ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER_IDX 63 +#define ENB_CONFIG_FRAME_TYPE_IDX 0 +#define ENB_CONFIG_TDD_CONFIG_IDX 1 +#define ENB_CONFIG_TDD_CONFIG_S_IDX 2 +#define ENB_CONFIG_PREFIX_TYPE_IDX 3 +#define ENB_CONFIG_PBCH_REPETITION_IDX 4 +#define ENB_CONFIG_EUTRA_BAND_IDX 5 +#define ENB_CONFIG_DOWNLINK_FREQUENCY_IDX 6 +#define ENB_CONFIG_UPLINK_FREQUENCY_OFFSET_IDX 7 +#define ENB_CONFIG_NID_CELL_IDX 8 +#define ENB_CONFIG_N_RB_DL_IDX 9 +#define ENB_CONFIG_CELL_MBSFN_IDX 10 +#define ENB_CONFIG_NB_ANT_PORTS_IDX 11 +#define ENB_CONFIG_PRACH_ROOT_IDX 12 +#define ENB_CONFIG_PRACH_CONFIG_INDEX_IDX 13 +#define ENB_CONFIG_PRACH_HIGH_SPEED_IDX 14 +#define ENB_CONFIG_PRACH_ZERO_CORRELATION_IDX 15 +#define ENB_CONFIG_PRACH_FREQ_OFFSET_IDX 16 +#define ENB_CONFIG_PUCCH_DELTA_SHIFT_IDX 17 +#define ENB_CONFIG_PUCCH_NRB_CQI_IDX 18 +#define ENB_CONFIG_PUCCH_NCS_AN_IDX 19 +#define ENB_CONFIG_PUCCH_N1_AN_IDX 20 +#define ENB_CONFIG_PDSCH_RS_EPRE_IDX 21 +#define ENB_CONFIG_PDSCH_PB_IDX 22 +#define ENB_CONFIG_PUSCH_N_SB_IDX 23 +#define ENB_CONFIG_PUSCH_HOPPINGMODE_IDX 24 +#define ENB_CONFIG_PUSCH_HOPPINGOFFSET_IDX 25 +#define ENB_CONFIG_PUSCH_ENABLE64QAM_IDX 26 +#define ENB_CONFIG_PUSCH_GROUP_HOPPING_EN_IDX 27 +#define ENB_CONFIG_PUSCH_GROUP_ASSIGNMENT_IDX 28 +#define ENB_CONFIG_PUSCH_SEQUENCE_HOPPING_EN_IDX 29 +#define ENB_CONFIG_PUSCH_NDMRS1_IDX 30 +#define ENB_CONFIG_PHICH_DURATION_IDX 31 +#define ENB_CONFIG_PHICH_RESOURCE_IDX 32 +#define ENB_CONFIG_SRS_ENABLE_IDX 33 +#define ENB_CONFIG_SRS_BANDWIDTH_CONFIG_IDX 34 +#define ENB_CONFIG_SRS_SUBFRAME_CONFIG_IDX 35 +#define ENB_CONFIG_SRS_ACKNACKST_CONFIG_IDX 36 +#define ENB_CONFIG_SRS_MAXUPPTS_IDX 37 +#define ENB_CONFIG_PUSCH_PO_NOMINAL_IDX 38 +#define ENB_CONFIG_PUSCH_ALPHA_IDX 39 +#define ENB_CONFIG_PUCCH_PO_NOMINAL_IDX 40 +#define ENB_CONFIG_MSG3_DELTA_PREAMBLE_IDX 41 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1_IDX 42 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1b_IDX 43 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2_IDX 44 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2A_IDX 45 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2B_IDX 46 +#define ENB_CONFIG_RACH_NUM_RA_PREAMBLES_IDX 47 +#define ENB_CONFIG_RACH_PREAMBLESGROUPACONFIG_IDX 48 +#define ENB_CONFIG_RACH_SIZEOFRA_PREAMBLESGROUPA_IDX 49 +#define ENB_CONFIG_RACH_MESSAGESIZEGROUPA_IDX 50 +#define ENB_CONFIG_RACH_MESSAGEPOWEROFFSETGROUPB_IDX 51 +#define ENB_CONFIG_RACH_POWERRAMPINGSTEP_IDX 52 +#define ENB_CONFIG_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_IDX 53 +#define ENB_CONFIG_RACH_PREAMBLETRANSMAX_IDX 54 +#define ENB_CONFIG_RACH_RARESPONSEWINDOWSIZE_IDX 55 +#define ENB_CONFIG_RACH_MACCONTENTIONRESOLUTIONTIMER_IDX 56 +#define ENB_CONFIG_RACH_MAXHARQMSG3TX_IDX 57 +#define ENB_CONFIG_PCCH_DEFAULT_PAGING_CYCLE_IDX 58 +#define ENB_CONFIG_PCCH_NB_IDX 59 +#define ENB_CONFIG_STRING_DRX_CONFIG_PRESENT_IDX 60 +#define ENB_CONFIG_STRING_DRX_ONDURATIONTIMER_IDX 61 +#define ENB_CONFIG_STRING_DRX_INACTIVITYTIMER_IDX 62 +#define ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER_IDX 63 #define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT_IDX 64 -#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_IDX 65 -#define ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE_IDX 66 -#define ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER_IDX 67 -#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 68 -#define ENB_CONFIG_UETIMERS_T300_IDX 69 -#define ENB_CONFIG_UETIMERS_T301_IDX 70 -#define ENB_CONFIG_UETIMERS_T310_IDX 71 -#define ENB_CONFIG_UETIMERS_T311_IDX 72 -#define ENB_CONFIG_UETIMERS_N310_IDX 73 -#define ENB_CONFIG_UETIMERS_N311_IDX 74 -#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 75 -#define ENB_CONFIG_MBMS_DEDICATED_SERVING_CELL_IDX 76 +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_IDX 65 +#define ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE_IDX 66 +#define ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER_IDX 67 +#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 68 +#define ENB_CONFIG_UETIMERS_T300_IDX 69 +#define ENB_CONFIG_UETIMERS_T301_IDX 70 +#define ENB_CONFIG_UETIMERS_T310_IDX 71 +#define ENB_CONFIG_UETIMERS_T311_IDX 72 +#define ENB_CONFIG_UETIMERS_N310_IDX 73 +#define ENB_CONFIG_UETIMERS_N311_IDX 74 +#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 75 +#define ENB_CONFIG_MBMS_DEDICATED_SERVING_CELL_IDX 76 /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* SRB1 configuration parameters section name */ @@ -867,15 +868,15 @@ typedef struct srb1_params_s { /*-------------------------------------------------------------------------------------------------------------------------------------*/ /* MME configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-------------------------------------------------------------------------------------------------------------------------------------*/ #define S1PARAMS_DESC { \ - {ENB_CONFIG_STRING_MME_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_MME_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX, NULL, 0, uptr:NULL, defintarrayval:NULL,TYPE_UINTARRAY, 6} \ - } + {ENB_CONFIG_STRING_MME_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_MME_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX, NULL, 0, uptr:NULL, defintarrayval:NULL, TYPE_UINTARRAY, 6} \ +} #define ENB_MME_IPV4_ADDRESS_IDX 0 #define ENB_MME_IPV6_ADDRESS_IDX 1 @@ -896,14 +897,14 @@ typedef struct srb1_params_s { /*-------------------------------------------------------------------------------------------------------------------------------------*/ -/* X2 configuration parameters */ +/* X2 configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-------------------------------------------------------------------------------------------------------------------------------------*/ #define X2PARAMS_DESC { \ - {ENB_CONFIG_STRING_TARGET_ENB_X2_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_TARGET_ENB_X2_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ - } + {ENB_CONFIG_STRING_TARGET_ENB_X2_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_TARGET_ENB_X2_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +} #define ENB_X2_IPV4_ADDRESS_IDX 0 #define ENB_X2_IPV6_ADDRESS_IDX 1 @@ -939,8 +940,9 @@ typedef struct srb1_params_s { #define ENB_INTERFACE_NAME_FOR_S1U_IDX 2 #define ENB_IPV4_ADDR_FOR_S1U_IDX 3 #define ENB_PORT_FOR_S1U_IDX 4 -#define ENB_IPV4_ADDR_FOR_X2C_IDX 5 -#define ENB_PORT_FOR_X2C_IDX 6 +#define ENB_IPV4_ADDR_FOR_X2C_IDX 5 +#define ENB_PORT_FOR_X2C_IDX 6 + /* S1 interface configuration parameters names */ #define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME" @@ -967,8 +969,6 @@ typedef struct srb1_params_s { {ENB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \ } - - /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* GTPU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -1018,54 +1018,53 @@ typedef struct srb1_params_s { /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* CU/DU configuration section names*/ -#define CONFIG_STRING_DU_LIST "DU" -#define CONFIG_STRING_CU_LIST "CU" -#define DU_TYPE_LTE 0 -#define DU_TYPE_WIFI 1 -#define ENB_CONFIG_STRING_CU_INTERFACES_CONFIG "CU_INTERFACES" -#define ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U "CU_INTERFACE_NAME_FOR_F1U" -#define ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U "CU_IPV4_ADDRESS_FOR_F1U" -#define ENB_CONFIG_STRING_CU_PORT_FOR_F1U "CU_PORT_FOR_F1U" -#define ENB_CONFIG_STRING_DU_TYPE "DU_TYPE" -#define ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE "F1_U_CU_TRANSPORT_TYPE" - -#define ENB_CONFIG_STRING_DU_INTERFACES_CONFIG "DU_INTERFACES" -#define ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U "DU_INTERFACE_NAME_FOR_F1U" -#define ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U "DU_IPV4_ADDRESS_FOR_F1U" -#define ENB_CONFIG_STRING_DU_PORT_FOR_F1U "DU_PORT_FOR_F1U" -#define ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE "F1_U_DU_TRANSPORT_TYPE" +#define CONFIG_STRING_DU_LIST "DU" +#define CONFIG_STRING_CU_LIST "CU" +#define DU_TYPE_LTE 0 +#define DU_TYPE_WIFI 1 +#define ENB_CONFIG_STRING_CU_INTERFACES_CONFIG "CU_INTERFACES" +#define ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U "CU_INTERFACE_NAME_FOR_F1U" +#define ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U "CU_IPV4_ADDRESS_FOR_F1U" +#define ENB_CONFIG_STRING_CU_PORT_FOR_F1U "CU_PORT_FOR_F1U" +#define ENB_CONFIG_STRING_DU_TYPE "DU_TYPE" +#define ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE "F1_U_CU_TRANSPORT_TYPE" +#define ENB_CONFIG_STRING_DU_INTERFACES_CONFIG "DU_INTERFACES" +#define ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U "DU_INTERFACE_NAME_FOR_F1U" +#define ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U "DU_IPV4_ADDRESS_FOR_F1U" +#define ENB_CONFIG_STRING_DU_PORT_FOR_F1U "DU_PORT_FOR_F1U" +#define ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE "F1_U_DU_TRANSPORT_TYPE" #define CONFIG_STRING_CU_BALANCING "CU_BALANCING" #define CUPARAMS_DESC { \ - {ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"eth0", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_CU_PORT_FOR_F1U, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE, NULL, 0, strptr:NULL, defstrval:"TCP", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DU_TYPE, NULL, 0, strptr:NULL, defstrval:"LTE", TYPE_STRING, 0}, \ - } + {ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"eth0", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_CU_PORT_FOR_F1U, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE, NULL, 0, strptr:NULL, defstrval:"TCP", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DU_TYPE, NULL, 0, strptr:NULL, defstrval:"LTE", TYPE_STRING, 0}, \ +} #define DUPARAMS_DESC { \ - {ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"eth0", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ - {ENB_CONFIG_STRING_DU_PORT_FOR_F1U, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE, NULL, 0, strptr:NULL, defstrval:"TCP", TYPE_STRING, 0}, \ - } + {ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"eth0", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_DU_PORT_FOR_F1U, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ + {ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE, NULL, 0, strptr:NULL, defstrval:"TCP", TYPE_STRING, 0}, \ +} #define CU_BAL_DESC { \ - {CONFIG_STRING_CU_BALANCING, NULL, 0, strptr:NULL, defstrval:"ALL", TYPE_STRING, 0}, \ - } + {CONFIG_STRING_CU_BALANCING, NULL, 0, strptr:NULL, defstrval:"ALL", TYPE_STRING, 0}, \ +} -#define CU_INTERFACE_F1U 0 -#define CU_ADDRESS_F1U 1 -#define CU_PORT_F1U 2 -#define CU_TYPE_F1U 3 +#define CU_INTERFACE_F1U 0 +#define CU_ADDRESS_F1U 1 +#define CU_PORT_F1U 2 +#define CU_TYPE_F1U 3 -#define DU_INTERFACE_F1U 0 -#define DU_ADDRESS_F1U 1 -#define DU_PORT_F1U 2 -#define DU_TYPE_F1U 3 -#define DU_TECH 4 +#define DU_INTERFACE_F1U 0 +#define DU_ADDRESS_F1U 1 +#define DU_PORT_F1U 2 +#define DU_TYPE_F1U 3 +#define DU_TECH 4 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/enb_paramdef_emtc.h b/openair2/ENB_APP/enb_paramdef_emtc.h index 3c23b2a557..1e7705ed1a 100644 --- a/openair2/ENB_APP/enb_paramdef_emtc.h +++ b/openair2/ENB_APP/enb_paramdef_emtc.h @@ -64,6 +64,7 @@ #define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" +#define ENB_CONFIG_STRING_PUSCH_REPETITION_LEVEL_CE_MODE_A_R13 "pusch_repetitionLevelCEmodeA_r13" #define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" #define ENB_CONFIG_STRING_SYSTEM_INFO_VALUE_TAG_LIST "system_info_value_tag_SI" #define ENB_CONFIG_STRING_FIRST_PREAMBLE_R13 "firstPreamble_r13" @@ -161,6 +162,7 @@ typedef struct ccparams_eMTC_s { char *pdsch_maxNumRepetitionCEmodeB_r13; char *pusch_maxNumRepetitionCEmodeA_r13; char *pusch_maxNumRepetitionCEmodeB_r13; + char *pusch_repetitionLevelCEmodeA_r13; } ccparams_eMTC_t; @@ -230,6 +232,7 @@ typedef struct ccparams_eMTC_s { {ENB_CONFIG_STRING_PRACH_HOPPING_OFFSET_R13, NULL, 0, iptr:&eMTCconfig->prach_HoppingOffset_r13, defintval:0, TYPE_INT, 0}, \ {ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pdsch_maxNumRepetitionCEmodeA_r13, defstrval:"r16", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pusch_maxNumRepetitionCEmodeA_r13, defstrval:"r8", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_PUSCH_REPETITION_LEVEL_CE_MODE_A_R13, NULL, 0, strptr:&eMTCconfig->pusch_repetitionLevelCEmodeA_r13, defstrval:"l1", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_CELL_SELECTION_INFO_CE_R13, NULL, 0, strptr:&eMTCconfig->cellSelectionInfoCE_r13, defstrval:"ENABLE", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_Q_RX_LEV_MIN_CE_R13, NULL, 0, iptr:&eMTCconfig->q_RxLevMinCE_r13, defintval:-70, TYPE_INT, 0}, \ {ENB_CONFIG_STRING_BANDWIDTH_REDUCED_ACCESS_RELATED_INFO_R13, NULL, 0, strptr:&eMTCconfig->bandwidthReducedAccessRelatedInfo_r13, defstrval:"ENABLE", TYPE_STRING, 0}, \ diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 1e6cc23c23..0ec7368d84 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -39,6 +39,7 @@ /* cell configuration section name */ #define GNB_CONFIG_STRING_GNB_LIST "gNBs" #define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset" +#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts" #define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon" #define GNB_CONFIG_STRING_PHYSCELLID "physCellId" #define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset" @@ -222,6 +223,7 @@ #define SSBPARAMS_DESC {{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,NULL,0,iptr:&ssb_SubcarrierOffset,defintval:0,TYPE_INT,0}} +#define PDSCHANTENNAPARAMS_DESC {{GNB_CONFIG_STRING_PDSCHANTENNAPORTS,NULL,0,iptr:&pdsch_AntennaPorts,defintval:1,TYPE_INT,0}} #define SCCPARAMS_DESC(scc) { \ {GNB_CONFIG_STRING_PHYSCELLID,NULL,0,i64ptr:scc->physCellId,defint64val:0,TYPE_INT64,0/*0*/}, \ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 61da86bb3f..0152d53122 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -59,8 +59,8 @@ //#include "RRC_config_tools.h" #include "gnb_paramdef.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" - #include "NR_asn_constant.h" +#include "executables/thread-common.h" #include "NR_SCS-SpecificCarrier.h" #include "NR_TDD-UL-DL-ConfigCommon.h" #include "NR_FrequencyInfoUL.h" @@ -78,10 +78,7 @@ #include "NR_EUTRA-MBSFN-SubframeConfig.h" extern uint16_t sf_ahead; -extern void set_parallel_conf(char *parallel_conf); -extern void set_worker_conf(char *worker_conf); -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); + extern int config_check_band_frequencies(int ind, int16_t band, uint32_t downlink_frequency, int32_t uplink_frequency_offset, uint32_t frame_type); @@ -259,7 +256,7 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,int ssbmap) { // fix DL and UL Allocation lists for (int i=scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count-1;i>=0;i--) { - printf("Checking element %d : %d\n",i,*scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0); + printf("Checking element %d : %ld\n",i,*scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0); if (*scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0>32) { printf("removing pdsch_TimeDomainAllocationList element %d\n",i); free(scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0); @@ -279,9 +276,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,int ssbmap) { scc->tdd_UL_DL_ConfigurationCommon->pattern2=NULL; } - if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) + if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) { free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=NULL; + } } void RCconfig_nr_flexran() @@ -521,6 +519,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t)); int ssb_SubcarrierOffset = 0; + int pdsch_AntennaPorts = 1; int ssb_bitmap=0xff; memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t)); prepare_scc(scc); @@ -528,6 +527,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0}; paramdef_t SSBsParams[] = SSBPARAMS_DESC; paramlist_def_t SSBsParamList = {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0}; + paramdef_t PDSCHANTENNAParams[] = PDSCHANTENNAPARAMS_DESC; + paramlist_def_t PDSCHANTENNAParamList = {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0}; ////////// Physical parameters @@ -561,6 +562,9 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { config_getlist(&SSBsParamList, NULL, 0, aprefix); if (SSBsParamList.numelt > 0) config_get(SSBsParams,sizeof(SSBsParams)/sizeof(paramdef_t),aprefix); + config_getlist(&PDSCHANTENNAParamList, NULL, 0, aprefix); + if (PDSCHANTENNAParamList.numelt > 0) config_get(PDSCHANTENNAParams,sizeof(PDSCHANTENNAParams)/sizeof(paramdef_t),aprefix); + config_getlist(&SCCsParamList, NULL, 0, aprefix); if (SCCsParamList.numelt > 0) { @@ -643,15 +647,14 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { sprintf(gnbpath,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k), + printf("SSB SCO %d\n",ssb_SubcarrierOffset); NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = ssb_SubcarrierOffset; + printf("pdsch_AntennaPorts %d\n",pdsch_AntennaPorts); + NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = pdsch_AntennaPorts; NRRRC_CONFIGURATION_REQ (msg_p).scc = scc; }// - - }//End for (k=0; k 0) diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 20a87c9111..f76970518e 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -67,83 +67,9 @@ typedef enum { #define CONFIG_STRING_ACTIVE_RUS "Active_RUs" /*------------------------------------------------------------------------------------------------------------------------------------------*/ -/* RUs configuration section name */ -#define CONFIG_STRING_RU_LIST "RUs" -#define CONFIG_STRING_RU_CONFIG "ru_config" -/* RUs configuration parameters name */ -#define CONFIG_STRING_RU_LOCAL_IF_NAME "local_if_name" -#define CONFIG_STRING_RU_LOCAL_ADDRESS "local_address" -#define CONFIG_STRING_RU_REMOTE_ADDRESS "remote_address" -#define CONFIG_STRING_RU_LOCAL_PORTC "local_portc" -#define CONFIG_STRING_RU_REMOTE_PORTC "remote_portc" -#define CONFIG_STRING_RU_LOCAL_PORTD "local_portd" -#define CONFIG_STRING_RU_REMOTE_PORTD "remote_portd" -#define CONFIG_STRING_RU_LOCAL_RF "local_rf" -#define CONFIG_STRING_RU_TRANSPORT_PREFERENCE "tr_preference" -#define CONFIG_STRING_RU_BAND_LIST "bands" -#define CONFIG_STRING_RU_GNB_LIST "gNB_instances" -#define CONFIG_STRING_RU_NB_TX "nb_tx" -#define CONFIG_STRING_RU_NB_RX "nb_rx" -#define CONFIG_STRING_RU_ATT_TX "att_tx" -#define CONFIG_STRING_RU_ATT_RX "att_rx" -#define CONFIG_STRING_RU_MAX_RS_EPRE "max_pdschReferenceSignalPower" -#define CONFIG_STRING_RU_MAX_RXGAIN "max_rxgain" -#define CONFIG_STRING_RU_IF_COMPRESSION "if_compression" -#define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" -#define CONFIG_STRING_RU_SDR_ADDRS "sdr_addrs" -#define CONFIG_STRING_RU_SDR_CLK_SRC "clock_src" - -#define RU_LOCAL_IF_NAME_IDX 0 -#define RU_LOCAL_ADDRESS_IDX 1 -#define RU_REMOTE_ADDRESS_IDX 2 -#define RU_LOCAL_PORTC_IDX 3 -#define RU_REMOTE_PORTC_IDX 4 -#define RU_LOCAL_PORTD_IDX 5 -#define RU_REMOTE_PORTD_IDX 6 -#define RU_TRANSPORT_PREFERENCE_IDX 7 -#define RU_LOCAL_RF_IDX 8 -#define RU_NB_TX_IDX 9 -#define RU_NB_RX_IDX 10 -#define RU_MAX_RS_EPRE_IDX 11 -#define RU_MAX_RXGAIN_IDX 12 -#define RU_BAND_LIST_IDX 13 -#define RU_GNB_LIST_IDX 14 -#define RU_ATT_TX_IDX 15 -#define RU_ATT_RX_IDX 16 -#define RU_IS_SLAVE_IDX 17 -#define RU_NBIOTRRC_LIST_IDX 18 -#define RU_SDR_ADDRS 19 -#define RU_SDR_CLK_SRC 20 -#define RU_SF_EXTENSION_IDX 21 -#define RU_END_OF_BURST_DELAY_IDX 22 - - - -/*-----------------------------------------------------------------------------------------------------------------------------------------*/ -/* RU configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-----------------------------------------------------------------------------------------------------------------------------------------*/ -#define GNBRUPARAMS_DESC { \ -{CONFIG_STRING_RU_LOCAL_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_LOCAL_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_REMOTE_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_LOCAL_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_REMOTE_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_LOCAL_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_REMOTE_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_TRANSPORT_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"udp_if5", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_LOCAL_RF, NULL, 0, strptr:NULL, defstrval:"yes", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_NB_TX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_NB_RX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_MAX_RS_EPRE, NULL, 0, iptr:NULL, defintval:-29, TYPE_INT, 0}, \ -{CONFIG_STRING_RU_MAX_RXGAIN, NULL, 0, iptr:NULL, defintval:120, TYPE_INT, 0}, \ -{CONFIG_STRING_RU_BAND_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFNRBANDS, TYPE_INTARRAY, 1}, \ -{CONFIG_STRING_RU_GNB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFGNBS, TYPE_INTARRAY, 1}, \ -{CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFGNBS, TYPE_INTARRAY, 1}, \ -} +/* RUs configuration for gNB is the same for eNB */ +/* Check file enb_paramdef.h */ /*---------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 879d0da6e0..0387d7a536 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -68,6 +68,7 @@ extern RAN_CONTEXT_t RC; +extern const uint8_t pusch_repetition_Table8_2_36213[3][4]; extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); @@ -98,6 +99,7 @@ void add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, sub_frame_t subframeP) { eNB_MAC_INST *mac = RC.mac[module_idP]; + eNB_RRC_INST *rrc = RC.rrc[module_idP]; COMMON_channels_t *cc = &mac->common_channels[CC_id]; uint8_t j; nfapi_ul_config_request_t *ul_req; @@ -108,6 +110,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; uint8_t sf_ahead_dl; uint8_t rvseq[4] = {0, 2, 3, 1}; + uint8_t pusch_maxNumRepetitionCEmodeA_r13; ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe]; ul_req_body = &ul_req->ul_config_request_body; AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", @@ -139,7 +142,13 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb); // Re13 fields ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1; + if (ra->rach_resource_type > 0) { + pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions= pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][ra->pusch_repetition_levels]; + } + else{ + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions=1; + } ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; ul_req_body->number_of_pdus++; @@ -235,6 +244,7 @@ void generate_Msg2(module_id_t module_idP, //------------------------------------------------------------------------------ { eNB_MAC_INST *mac = RC.mac[module_idP]; + eNB_RRC_INST *rrc = RC.rrc[module_idP]; COMMON_channels_t *cc = mac->common_channels; uint8_t *vrb_map = NULL; int first_rb = 0; @@ -246,6 +256,7 @@ void generate_Msg2(module_id_t module_idP, dl_req_body = &mac->DL_req[CC_idP].dl_config_request_body; dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); + uint8_t PUSCH_Rep_Level; int rmax = 0; int rep = 0; int reps = 0; @@ -257,6 +268,13 @@ void generate_Msg2(module_id_t module_idP, uint16_t absSF = (10 * frameP) + subframeP; uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe; + if (ra->rach_resource_type > 0) { + PUSCH_Rep_Level= *(rrc->configuration.pusch_repetitionLevelCEmodeA_r13[CC_idP]); + } + else { + PUSCH_Rep_Level= 0; + } + if (absSF > absSF_Msg2) { return; // we're not ready yet } @@ -396,6 +414,8 @@ void generate_Msg2(module_id_t module_idP, ra->msg2_mpdcch_repetition_cnt++; } + ra->pusch_repetition_levels = PUSCH_Rep_Level; + if((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { /* Program PDSCH */ LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", @@ -1218,6 +1238,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, UE_id = find_UE_id(module_idP, ra->rnti); DevAssert(UE_id != -1); mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; + mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].pusch_repetition_levels=ra->pusch_repetition_levels; cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index c69d533558..469aade040 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -200,7 +200,8 @@ schedule_SIB1_MBMS(module_id_t module_idP, // Note: definition of k above and rvidx from 36.321 section 5.3.1 rvidx = (((3 * k) >> 1) + (k & 1)) & 3; i = cc->SIB1_BR_cnt & (m - 1); - n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; + if(Sj) + n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, "schedulingInfoSIB1_BR_r13 %d > 18\n", @@ -429,7 +430,8 @@ schedule_SIB1_BR(module_id_t module_idP, // Note: definition of k above and rvidx from 36.321 section 5.3.1 rvidx = (((3 * k) >> 1) + (k & 1)) & 3; i = cc->SIB1_BR_cnt & (m - 1); - n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; + if(Sj) + n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 0xFFFF, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, "schedulingInfoSIB1_BR_r13 %d > 18\n", @@ -595,7 +597,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; // check if the SI is to be scheduled now - int period_in_sf; + int period_in_sf = 0; if ((si_Periodicity >= 0) && (si_Periodicity < 25)) { // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index b1e1fb5d73..04757dab16 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -171,7 +171,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB], DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]) { eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; @@ -573,8 +573,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, uint8_t slice_allocation[MAX_NUM_CCs][N_RBG_MAX]; int UE_id, i; uint16_t j,c; - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0}; rnti_t rnti; @@ -617,7 +617,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, frameP, subframeP, min_rb_unit, - (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, + (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required, rballoc_sub, MIMO_mode_indicator, mbsfn_flag); @@ -631,7 +631,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, assign_rbs_required(Mod_id, 0, frameP, subframeP, nb_rbs_required, min_rb_unit); #else - memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use], sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use], sizeof(uint16_t)*MAX_NUM_CCs*MAX_MOBILES_PER_ENB); #endif dlsch_scheduler_pre_ue_select_fairRR(Mod_id,frameP,subframeP, mbsfn_flag,nb_rbs_required,dlsch_ue_select); @@ -701,8 +701,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, CC_id, N_RBG[CC_id], min_rb_unit[CC_id], - (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, - (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining, + (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required, + (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required_remaining, rballoc_sub, slice_allocation, MIMO_mode_indicator); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h index 8c90118609..5355a614a6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h @@ -82,7 +82,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( frame_t frameP, sub_frame_t subframeP, int* mbsfn_flag, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB], DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]); void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 6f712e63b8..e3b74d388c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -84,6 +84,14 @@ uint8_t rb_table[34] = { 81, 90, 96, 100 // 30-33 }; +// This table hold the possible number of MTC repetition for CE ModeA +const uint8_t pusch_repetition_Table8_2_36213[3][4]= +{ + {1 , 2 , 4 , 8 }, + {1 , 4 , 8 , 16}, + {1 , 4 , 16, 32} +}; + extern mui_t rrc_eNB_mui; //----------------------------------------------------------------------------- @@ -293,16 +301,22 @@ rx_sdu(const module_id_t enb_mod_idP, if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } else { - // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!! - ra->msg3_round++; - /* Prepare handling of retransmission */ - get_Msg3allocret(&mac->common_channels[CC_idP], - ra->Msg3_subframe, - ra->Msg3_frame, - &ra->Msg3_frame, - &ra->Msg3_subframe); - // prepare handling of retransmission - add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP); + if (ra->rach_resource_type > 0) { + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // TODO: Currently we don't support retransmission of Msg3 ( If in error Cancel RA procedure and reattach) + } + else + { + // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!! + ra->msg3_round++; + /* Prepare handling of retransmission */ + get_Msg3allocret(&mac->common_channels[CC_idP], + ra->Msg3_subframe, + ra->Msg3_frame, + &ra->Msg3_frame, + &ra->Msg3_subframe); + // prepare handling of retransmission + add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP); + } } /* TODO: program NACK for PHICH? */ @@ -1925,10 +1939,13 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, int tpc = 0; int cqi_req = 0; eNB_MAC_INST *eNB = RC.mac[module_idP]; + eNB_RRC_INST *rrc = RC.rrc[module_idP]; COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &(eNB->UE_list); UE_TEMPLATE *UE_template = NULL; UE_sched_ctrl_t *UE_sched_ctrl = NULL; + uint8_t Total_Num_Rep_ULSCH,pusch_maxNumRepetitionCEmodeA_r13; + uint8_t UL_Scheduling_DCI_SF,UL_Scheduling_DCI_Frame_Even_Odd_Flag; //TODO: To be removed after scheduler relaxation Task if (sched_subframeP < subframeP) { sched_frame++; @@ -1937,11 +1954,9 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, nfapi_hi_dci0_request_body_t *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body); nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = NULL; nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body); - - /* If frameP odd don't schedule */ - if ((frameP & 1) == 1) { - return; - } + nfapi_ul_config_request_body_t *ul_req_body_Rep; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + nfapi_ul_config_request_pdu_t *ul_config_pdu_Rep; /* Loop over all active UEs */ for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { @@ -1999,8 +2014,18 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer); + pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]); + Total_Num_Rep_ULSCH = pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][UE_template->pusch_repetition_levels]; + UL_Scheduling_DCI_SF = (40-4 - Total_Num_Rep_ULSCH)%10; //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task + UL_Scheduling_DCI_Frame_Even_Odd_Flag= ! (((40-4 - Total_Num_Rep_ULSCH)/10 )%2); //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task + + /* If frameP odd don't schedule */ + if ((frameP&1) == UL_Scheduling_DCI_Frame_Even_Odd_Flag) //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task + { + + //if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) { - if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == 5)) { + if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == UL_Scheduling_DCI_SF)) { /* * if there is information on bsr of DCCH, DTCH, * or if there is UL_SR, @@ -2151,7 +2176,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = UE_template->pusch_repetition_levels; AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; @@ -2201,7 +2226,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ); fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, - 1, // total_number_of_repetitions + Total_Num_Rep_ULSCH, // total_number_of_repetitions 1, // repetition_number (frameP * 10) + subframeP); ul_req_tmp->number_of_pdus++; @@ -2330,5 +2355,24 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, } } // UE_is_to_be_scheduled } // ULCCs - } // loop over UE_id + } // loop over UE_id + } // Schedule new ULSCH + + // This section is to repeat ULSCH PDU for a number of MTC repetitions + for(int i=0;inumber_of_pdus;i++) + { + ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[i]; + if (ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) // Repeat ULSCH PDUs only + continue ; + + if(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number < ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions) + { + ul_req_body_Rep = &eNB->UL_req_tmp[CC_id][(sched_subframeP+1)%10].ul_config_request_body; + ul_config_pdu_Rep = &ul_req_body_Rep->ul_config_pdu_list[ul_req_body_Rep->number_of_pdus]; + memcpy ((void *) ul_config_pdu_Rep, ul_config_pdu, sizeof (nfapi_ul_config_request_pdu_t)); + ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++; + ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel13.repetition_number = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number +1; + ul_req_body_Rep->number_of_pdus++; + } //repetition_number < total_number_of_repetitions + } // For loop on PDUs } diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 556bf2176f..979ec4dace 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -904,9 +904,11 @@ typedef struct { uint16_t mpdcch_repetition_cnt; frame_t Msg2_frame; sub_frame_t Msg2_subframe; - +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// Repetition column in pusch_repetition Table 8.2.b in TS36.213 + uint8_t pusch_repetition_levels; +#endif LTE_PhysicalConfigDedicated_t *physicalConfigDedicated; - } UE_TEMPLATE; /*! \brief scheduling control information set through an API (not used)*/ @@ -1113,7 +1115,10 @@ typedef struct { uint8_t msg2_narrowband; uint8_t msg34_narrowband; int msg4_rrc_sdu_length; - +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /// Repetition column in pusch_repetition Table 8.2.b in TS36.213 + uint8_t pusch_repetition_levels; +#endif int32_t crnti_rrc_mui; int8_t crnti_harq_pid; } RA_t; diff --git a/openair2/LAYER2/MAC/mac_vars.h b/openair2/LAYER2/MAC/mac_vars.h index d9b4b9f907..bd25bd6047 100644 --- a/openair2/LAYER2/MAC/mac_vars.h +++ b/openair2/LAYER2/MAC/mac_vars.h @@ -26,7 +26,6 @@ * \version 1.0 * \email navid.nikaein@eurecom.fr * @ingroup _mac - */ @@ -102,7 +101,6 @@ MAC_RLC_XFACE *Mac_rlc_xface; int pCC_id[NUMBER_OF_eNB_MAX]; - eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8 @@ -126,7 +124,6 @@ DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; DCI1_5MHz_TDD_t DLSCH_alloc_pdu; DCI1C_5MHz_t MCCH_alloc_pdu; - DCI0_5MHz_FDD_t UL_alloc_pdu_fdd; DCI1A_5MHz_FDD_t DLSCH_alloc_pdu1A_fdd; diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 8fb8d44e0a..4e139dcf92 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -146,7 +146,7 @@ void mac_top_init_eNB(void) RC.mac = mac; - AssertFatal(rlc_module_init() == 0, + AssertFatal(rlc_module_init(1) == 0, "Could not initialize RLC layer\n"); // These should be out of here later @@ -184,7 +184,7 @@ int rlcmac_init_global_param(void) LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n"); - if (rlc_module_init() != 0) { + if (rlc_module_init(1) != 0) { return (-1); } diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c index f482806e1d..e8b0593717 100644 --- a/openair2/LAYER2/MAC/main_ue.c +++ b/openair2/LAYER2/MAC/main_ue.c @@ -110,7 +110,7 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer, int rlcmac_init_global_param_ue(void) { LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n"); - if (rlc_module_init() != 0) { + if (rlc_module_init(0) != 0) { return (-1); } diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 44561a7011..6999e4ab5e 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -125,7 +125,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, COMMON_channels_t *cc = &eNB->common_channels[CC_id]; uint8_t *rar = (uint8_t *)(dlsch_buffer + 1); uint32_t rballoc = 0; - uint32_t reps = 0; uint32_t ULdelay = 0; uint32_t cqireq = 0; uint32_t mpdcch_nb_index = 0; @@ -151,7 +150,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, input_buffer_length = 6; N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth); /* UL Grant */ - reps = 0; ra->msg3_mcs = 7; TPC = 3; // no power increase ULdelay = 0; @@ -161,7 +159,7 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB, uint32_t buffer = 0; buffer |= ra->msg34_narrowband << (16 + (4 - N_NB_index)); buffer |= ((rballoc & 0x0F) << (12 + (4 - N_NB_index))); - buffer |= ((reps & 0x03) << (10 + (4 - N_NB_index))); + buffer |= ((ra->pusch_repetition_levels & 0x03) << (10 + (4 - N_NB_index))); buffer |= ((ra->msg3_mcs & 0x07) << (7 + (4 - N_NB_index))); buffer |= ((TPC & 0x07) << (4 + (4 - N_NB_index))); buffer |= ((cqireq & 0x01) << (3 + (4 - N_NB_index))); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 4fc48d3999..eb8866869e 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -42,9 +42,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac) { fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; NR_ServingCellConfigCommon_t *scc = mac->scc; - +/* mac->if_module->phy_config_request(&mac->phy_config); - cfg->sch_config.physical_cell_id = *scc->physCellId; cfg->sch_config.ssb_scg_position_in_burst = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]; @@ -127,6 +126,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac) { for (int i=0;ipusch_config.num_PUSCHTimeDomainResourceAllocations;i++) { cfg->pusch_config.PUSCHTimeDomainResourceAllocation_k2[i]=*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2; } +*/ } int nr_rrc_mac_config_req_ue( @@ -135,8 +135,8 @@ int nr_rrc_mac_config_req_ue( uint8_t gNB_index, NR_MIB_t *mibP, NR_ServingCellConfigCommon_t *sccP, - NR_MAC_CellGroupConfig_t *mac_cell_group_configP, - NR_PhysicalCellGroupConfig_t *phy_cell_group_configP, + // NR_MAC_CellGroupConfig_t *mac_cell_group_configP, + // NR_PhysicalCellGroupConfig_t *phy_cell_group_configP, NR_SpCellConfig_t *spCell_ConfigP ){ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -147,123 +147,87 @@ int nr_rrc_mac_config_req_ue( NR_ServingCellConfigCommon_t *scc; if(mibP != NULL){ - mac->mib = mibP; // update by every reception + mac->mib = mibP; // update by every reception } - if(mac_cell_group_configP != NULL){ - if(mac_cell_group_configP->drx_Config != NULL ){ - switch(mac_cell_group_configP->drx_Config->present){ - case NR_SetupRelease_DRX_Config_PR_NOTHING: - break; - case NR_SetupRelease_DRX_Config_PR_release: - mac->drx_Config = NULL; - break; - case NR_SetupRelease_DRX_Config_PR_setup: - mac->drx_Config = mac_cell_group_configP->drx_Config->choice.setup; - break; - default: - break; - } - } - if(mac_cell_group_configP->schedulingRequestConfig != NULL ){ - mac->schedulingRequestConfig = mac_cell_group_configP->schedulingRequestConfig; - } - - if(mac_cell_group_configP->bsr_Config != NULL ){ - mac->bsr_Config = mac_cell_group_configP->bsr_Config; - } - - if(mac_cell_group_configP->tag_Config != NULL ){ - mac->tag_Config = mac_cell_group_configP->tag_Config; - } - - if(mac_cell_group_configP->phr_Config != NULL ){ - switch(mac_cell_group_configP->phr_Config->present){ - case NR_SetupRelease_PHR_Config_PR_NOTHING: - break; - case NR_SetupRelease_PHR_Config_PR_release: - mac->phr_Config = NULL; - break; - case NR_SetupRelease_PHR_Config_PR_setup: - mac->phr_Config = mac_cell_group_configP->phr_Config->choice.setup; - break; - default: - break; - } - - } - - if(phy_cell_group_configP->cs_RNTI != NULL ){ - switch(phy_cell_group_configP->cs_RNTI->present){ - case NR_SetupRelease_RNTI_Value_PR_NOTHING: - break; - case NR_SetupRelease_RNTI_Value_PR_release: - mac->cs_RNTI = NULL; - break; - case NR_SetupRelease_RNTI_Value_PR_setup: - mac->cs_RNTI = &phy_cell_group_configP->cs_RNTI->choice.setup; - break; - default: - break; - } - - } - - } - if(phy_cell_group_configP != NULL ){ - //config_phy(phy_cell_group_config, NULL); - } - -// TODO check - + if(spCell_ConfigP != NULL ){ - mac->servCellIndex = spCell_ConfigP->servCellIndex; - if (spCell_ConfigP->reconfigurationWithSync) { - mac->scc = spCell_ConfigP->reconfigurationWithSync->spCellConfigCommon; - config_common_ue(mac); + mac->servCellIndex = spCell_ConfigP->servCellIndex; + if (spCell_ConfigP->reconfigurationWithSync) { + mac->scc = spCell_ConfigP->reconfigurationWithSync->spCellConfigCommon; + config_common_ue(mac); + mac->crnti = spCell_ConfigP->reconfigurationWithSync->newUE_Identity; + LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); + } + mac->scd = spCell_ConfigP->spCellConfigDedicated; + + /* + if(mac_cell_group_configP != NULL){ + if(mac_cell_group_configP->drx_Config != NULL ){ + switch(mac_cell_group_configP->drx_Config->present){ + case NR_SetupRelease_DRX_Config_PR_NOTHING: + break; + case NR_SetupRelease_DRX_Config_PR_release: + mac->drx_Config = NULL; + break; + case NR_SetupRelease_DRX_Config_PR_setup: + mac->drx_Config = mac_cell_group_configP->drx_Config->choice.setup; + break; + default: + break; + } } - mac->scd = spCell_ConfigP->spCellConfigDedicated; - } - - -#if 0 - if(serving_cell_config != NULL ){ - if(serving_cell_config->tdd_UL_DL_ConfigurationDedicated != NULL ){ - mac->tdd_UL_DL_ConfigurationDedicated = serving_cell_config->tdd_UL_DL_ConfigurationDedicated; - } - - if(spcell_config->initialDownlinkBWP != NULL ){ - mac->init_DL_BWP = spcell_config->initialDownlinkBWP; - } - - // storage list of DL BWP config. TODO should be modify to maintain(add/release) a list inside MAC instance, this implementation just use for one-shot RRC configuration setting. - if(spcell_config->downlinkBWP_ToAddModList != NULL ){ - mac->BWP_Downlink_list = spcell_config->downlinkBWP_ToAddModList->list; - mac->BWP_Downlink_count = spcell_config->downlinkBWP_ToAddModList->count; - } - - if(spcell_config->bwp_InactivityTimer != NULL ){ - mac->bwp_InactivityTimer = spcell_config->bwp_InactivityTimer; - } - - if(spcell_config->defaultDownlinkBWP_Id != NULL ){ - mac->defaultDownlinkBWP_Id = spcell_config->defaultDownlinkBWP_Id; - } - - if(spcell_config->pdsch_ServingCellConfig != NULL ){ - mac->pdsch_ServingCellConfig = spcell_config->pdsch_ServingCellConfig; - } - - if(spcell_config->csi_MeasConfig != NULL ){ - mac->csi_MeasConfig = spcell_config->csi_MeasConfig; - } - - spcell_config->tag_Id = spcell_config.tag_Id; - } -#endif - //scell config not yet - + + if(mac_cell_group_configP->schedulingRequestConfig != NULL ){ + mac->schedulingRequestConfig = mac_cell_group_configP->schedulingRequestConfig; + } + + if(mac_cell_group_configP->bsr_Config != NULL ){ + mac->bsr_Config = mac_cell_group_configP->bsr_Config; + } + + if(mac_cell_group_configP->tag_Config != NULL ){ + mac->tag_Config = mac_cell_group_configP->tag_Config; + } + + if(mac_cell_group_configP->phr_Config != NULL ){ + switch(mac_cell_group_configP->phr_Config->present){ + case NR_SetupRelease_PHR_Config_PR_NOTHING: + break; + case NR_SetupRelease_PHR_Config_PR_release: + mac->phr_Config = NULL; + break; + case NR_SetupRelease_PHR_Config_PR_setup: + mac->phr_Config = mac_cell_group_configP->phr_Config->choice.setup; + break; + default: + break; + } + } + } + + + if(phy_cell_group_configP != NULL ){ + if(phy_cell_group_configP->cs_RNTI != NULL ){ + switch(phy_cell_group_configP->cs_RNTI->present){ + case NR_SetupRelease_RNTI_Value_PR_NOTHING: + break; + case NR_SetupRelease_RNTI_Value_PR_release: + mac->cs_RNTI = NULL; + break; + case NR_SetupRelease_RNTI_Value_PR_setup: + mac->cs_RNTI = &phy_cell_group_configP->cs_RNTI->choice.setup; + break; + default: + break; + } + } + } + */ + } + return 0; + } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 0240be5a18..ac9ead3d91 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -56,6 +56,7 @@ #include "NR_ServingCellConfig.h" #include "fapi_nr_ue_interface.h" #include "NR_IF_Module.h" +#include "../NR_MAC_gNB/nr_mac_common.h" #include "PHY/defs_nr_common.h" @@ -63,10 +64,18 @@ typedef enum { SFN_C_MOD_2_EQ_0, - SFN_C_MOD_2_EQ_1 + SFN_C_MOD_2_EQ_1, + SFN_C_IMPOSSIBLE } SFN_C_TYPE; +#define MAX_NUM_BWP 2 + +typedef enum { + RA_IDLE=0, + WAIT_RAR=1, + WAIT_CONTENTION_RESOLUTION=2 +} RA_state_t; /*!\brief Top level UE MAC structure */ typedef struct { @@ -81,20 +90,27 @@ typedef struct { NR_PHR_Config_t *phr_Config; NR_RNTI_Value_t *cs_RNTI; NR_MIB_t *mib; - + + NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP]; + NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP]; + NR_ControlResourceSet_t *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP]; + NR_SearchSpace_t *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP][FAPI_NR_MAX_SS_PER_CORESET]; + /// Type0-PDCCH seach space fapi_nr_dl_config_dci_dl_pdu_rel15_t type0_pdcch_dci_config; uint32_t type0_pdcch_ss_mux_pattern; SFN_C_TYPE type0_pdcch_ss_sfn_c; uint32_t type0_pdcch_ss_n_c; uint32_t type0_pdcch_consecutive_slots; - - /// Random access parameter + /// state of RA procedure + RA_state_t ra_state; + /// RA-rnti uint16_t ra_rnti; - //BWP params - NR_BWP_PARMS initial_bwp_dl; - NR_BWP_PARMS initial_bwp_ul; + /// Temporary CRNTI + uint16_t t_crnti; + /// CRNTI + uint16_t crnti; //// FAPI-like interface message fapi_nr_tx_request_t tx_request; @@ -137,7 +153,139 @@ typedef enum frequency_range_e { FR2 } frequency_range_t; +typedef struct { + uint8_t identifier_dci_formats ; // 0 IDENTIFIER_DCI_FORMATS: + uint8_t carrier_ind ; // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] + uint8_t sul_ind_0_1 ; // 2 SUL_IND_0_1: + uint8_t slot_format_ind ; // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] + uint8_t pre_emption_ind ; // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits + uint8_t block_number ; // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3 + uint8_t close_loop_ind ; // 6 CLOSE_LOOP_IND: + uint8_t bandwidth_part_ind ; // 7 BANDWIDTH_PART_IND: + uint8_t short_message_ind ; // 8 SHORT_MESSAGE_IND: + uint8_t short_messages ; // 9 SHORT_MESSAGES: + uint16_t freq_dom_resource_assignment_UL; // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered + // (NOTE 1) If DCI format 0_0 is monitored in common search space + // and if the number of information bits in the DCI format 0_0 prior to padding + // is larger than the payload size of the DCI format 1_0 monitored in common search space + // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 + // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0 + uint16_t freq_dom_resource_assignment_DL; // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + uint8_t time_dom_resource_assignment ; // 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + // where I the number of entries in the higher layer parameter pusch-AllocationList + uint8_t vrb_to_prb_mapping ; // 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + uint8_t prb_bundling_size_ind ; // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] + uint8_t rate_matching_ind ; // 15 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set + uint8_t zp_csi_rs_trigger ; // 16 ZP_CSI_RS_TRIGGER: + uint8_t freq_hopping_flag ; // 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 + uint8_t tb1_mcs ; // 18 TB1_MCS: + uint8_t tb1_ndi ; // 19 TB1_NDI: + uint8_t tb1_rv ; // 20 TB1_RV: + uint8_t tb2_mcs ; // 21 TB2_MCS: + uint8_t tb2_ndi ; // 22 TB2_NDI: + uint8_t tb2_rv ; // 23 TB2_RV: + uint8_t mcs ; // 24 MCS: + uint8_t ndi ; // 25 NDI: + uint8_t rv ; // 26 RV: + uint8_t harq_process_number ; // 27 HARQ_PROCESS_NUMBER: + uint8_t dai ; // 28 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI + // 0 otherwise + uint8_t first_dai ; // 29 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK + uint8_t second_dai ; // 30 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks + uint8_t tb_scaling ; // 31 TB_SCALING: + uint8_t tpc_pusch ; // 32 TPC_PUSCH: + uint8_t tpc_pucch ; // 33 TPC_PUCCH: + uint8_t pucch_resource_ind ; // 34 PUCCH_RESOURCE_IND: + uint8_t pdsch_to_harq_feedback_time_ind ; // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: + uint8_t srs_resource_ind ; // 36 SRS_RESOURCE_IND: + uint8_t precod_nbr_layers ; // 37 PRECOD_NBR_LAYERS: + uint8_t antenna_ports ; // 38 ANTENNA_PORTS: + uint8_t tci ; // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits + uint8_t srs_request ; // 40 SRS_REQUEST: + uint8_t tpc_cmd ; // 41 TPC_CMD: + uint8_t csi_request ; // 42 CSI_REQUEST: + uint8_t cbgti ; // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH + uint8_t cbgfi ; // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator + uint8_t ptrs_dmrs ; // 45 PTRS_DMRS: + uint8_t beta_offset_ind ; // 46 BETA_OFFSET_IND: + uint8_t dmrs_seq_ini ; // 47 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding + // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise + uint8_t ul_sch_ind ; // 48 UL_SCH_IND: value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH + uint16_t padding_nr_dci ; // 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space + // and if the number of information bits in the DCI format 0_0 prior to padding + // is less than the payload size of the DCI format 1_0 monitored in common search space + // zeros shall be appended to the DCI format 0_0 + // until the payload size equals that of the DCI format 1_0 + uint8_t sul_ind_0_0 ; // 50 SUL_IND_0_0: + uint8_t ra_preamble_index ; // 51 RA_PREAMBLE_INDEX: + uint8_t sul_ind_1_0 ; // 52 SUL_IND_1_0: + uint8_t ss_pbch_index ; // 53 SS_PBCH_INDEX + uint8_t prach_mask_index ; // 54 PRACH_MASK_INDEX + uint8_t reserved_nr_dci ; // 55 RESERVED_NR_DCI +} nr_dci_pdu_rel15_t; + #define NUM_SLOT_FRAME 10 +#define NBR_NR_FORMATS 8 // The number of formats is 8 (0_0, 0_1, 1_0, 1_1, 2_0, 2_1, 2_2, 2_3) +#define NBR_NR_DCI_FIELDS 56 // The number of different dci fields defined in TS 38.212 subclause 7.3.1 + +#define IDENTIFIER_DCI_FORMATS 0 +#define CARRIER_IND 1 +#define SUL_IND_0_1 2 +#define SLOT_FORMAT_IND 3 +#define PRE_EMPTION_IND 4 +#define BLOCK_NUMBER 5 +#define CLOSE_LOOP_IND 6 +#define BANDWIDTH_PART_IND 7 +#define SHORT_MESSAGE_IND 8 +#define SHORT_MESSAGES 9 +#define FREQ_DOM_RESOURCE_ASSIGNMENT_UL 10 +#define FREQ_DOM_RESOURCE_ASSIGNMENT_DL 11 +#define TIME_DOM_RESOURCE_ASSIGNMENT 12 +#define VRB_TO_PRB_MAPPING 13 +#define PRB_BUNDLING_SIZE_IND 14 +#define RATE_MATCHING_IND 15 +#define ZP_CSI_RS_TRIGGER 16 +#define FREQ_HOPPING_FLAG 17 +#define TB1_MCS 18 +#define TB1_NDI 19 +#define TB1_RV 20 +#define TB2_MCS 21 +#define TB2_NDI 22 +#define TB2_RV 23 +#define MCS 24 +#define NDI 25 +#define RV 26 +#define HARQ_PROCESS_NUMBER 27 +#define DAI_ 28 +#define FIRST_DAI 29 +#define SECOND_DAI 30 +#define TB_SCALING 31 +#define TPC_PUSCH 32 +#define TPC_PUCCH 33 +#define PUCCH_RESOURCE_IND 34 +#define PDSCH_TO_HARQ_FEEDBACK_TIME_IND 35 +#define SRS_RESOURCE_IND 36 +#define PRECOD_NBR_LAYERS 37 +#define ANTENNA_PORTS 38 +#define TCI 39 +#define SRS_REQUEST 40 +#define TPC_CMD 41 +#define CSI_REQUEST 42 +#define CBGTI 43 +#define CBGFI 44 +#define PTRS_DMRS 45 +#define BETA_OFFSET_IND 46 +#define DMRS_SEQ_INI 47 +#define UL_SCH_IND 48 +#define PADDING_NR_DCI 49 +#define SUL_IND_0_0 50 +#define RA_PREAMBLE_INDEX 51 +#define SUL_IND_1_0 52 +#define SS_PBCH_INDEX 53 +#define PRACH_MASK_INDEX 54 +#define RESERVED_NR_DCI 55 + /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 5ab6080d79..485327a9ae 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -20,7 +20,7 @@ */ /* \file proto.h - * \brief MAC functions prototypes for eNB and UE + * \brief MAC functions prototypes for gNB and UE * \author R. Knopp, K.H. HSU * \date 2018 * \version 0.1 @@ -64,18 +64,14 @@ int8_t nr_ue_decode_mib( \param gNB_index gNB index \param mibP pointer to RRC message MIB \param sccP pointer to ServingCellConfigCommon structure, - \param mac_cell_group_configP pointer to RRC message MAC-related in cell group config - \param phy_cell_group_configP pointer to RRC message PHY-related in cell group config \param spcell_configP pointer to RRC message serving cell config*/ -int nr_rrc_mac_config_req_ue( - module_id_t module_id, - int cc_id, - uint8_t gNB_index, - NR_MIB_t *mibP, +int nr_rrc_mac_config_req_ue( + module_id_t module_id, + int cc_idP, + uint8_t gNB_index, + NR_MIB_t *mibP, NR_ServingCellConfigCommon_t *sccP, - NR_MAC_CellGroupConfig_t *mac_cell_group_configP, - NR_PhysicalCellGroupConfig_t *phy_cell_group_configP, - NR_SpCellConfig_t *spcell_configP ); + NR_SpCellConfig_t *spCell_ConfigP); /**\brief initialization NR UE MAC instance(s), total number of MAC instance based on NB_NR_UE_MAC_INST*/ int nr_l2_init_ue(void); @@ -118,7 +114,8 @@ uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe); -int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format); +int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format); +int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index,fapi_nr_dci_indication_pdu_t *dci); uint32_t get_ssb_frame(uint32_t test); uint32_t get_ssb_slot(uint32_t ssb_index); @@ -132,9 +129,23 @@ void nr_ue_process_mac_pdu( uint8_t CC_id, uint8_t *pduP, uint16_t mac_pdu_len, - uint8_t eNB_index); + uint8_t gNB_index); int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len); +void nr_ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP, uint8_t * sdu, uint16_t sdu_len, uint8_t gNB_index); + +void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot); + +int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, + int dci_format, + uint8_t dci_length, + uint16_t rnti, + uint64_t *dci_pdu, + nr_dci_pdu_rel15_t *nr_pdci_info_extracted); + + + + #endif /** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 3688514745..0478a6b7d5 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -32,6 +32,7 @@ //#include "defs.h" #include "mac_proto.h" +#include "executables/nr-softmodem.h" static NR_UE_MAC_INST_t *nr_ue_mac_inst; @@ -45,6 +46,14 @@ nr_l2_init_ue(void) //init mac here nr_ue_mac_inst = (NR_UE_MAC_INST_t *)malloc(sizeof(NR_UE_MAC_INST_t)*NB_NR_UE_MAC_INST); + if (IS_SOFTMODEM_NOS1){ + if (rlc_module_init(0) != 0) { + LOG_I(RLC, "Problem at RLC initiation \n"); + } + pdcp_layer_init(); + nr_ip_over_LTE_DRB_preconfiguration(); + } + return (1); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c new file mode 100644 index 0000000000..412fcf09e3 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -0,0 +1,178 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* \file nr_ue_dci_configuration.c + * \brief functions for generating dci search procedures based on RRC Serving Cell Group Configuration + * \author R. Knopp + * \date 2020 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ + +#include "mac_proto.h" +#include "mac_defs.h" +#include "assertions.h" +#include "LAYER2/NR_MAC_UE/mac_extern.h" +#include "mac_defs.h" +#include + +#ifdef NR_PDCCH_DCI_TOOLS_DEBUG +#define LOG_DCI_D(a...) printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) ->" a) +#else +#define LOG_DCI_D(a...) +#endif +#define LOG_DCI_PARM(a...) LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci)" a) + + +void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) { + + LOG_D(MAC,"Filling search candidates for DCI\n"); + + rel15->number_of_candidates=1; + rel15->CCE[0]=0; + rel15->L[0]=4; +} + +void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot) { + + // check if DL slot + if (is_nr_DL_slot(mac->scc->tdd_UL_DL_ConfigurationCommon,slot)==1) { + + // get BWP 1, Coreset 0, SearchSpace 0 + if (mac->DLbwp[0]==NULL) { + AssertFatal(mac->scd->downlinkBWP_ToAddModList!=NULL,"downlinkBWP_ToAddModList is null\n"); + AssertFatal(mac->scd->downlinkBWP_ToAddModList->list.count==1,"downlinkBWP_ToAddModList->list->count is %d\n", + mac->scd->downlinkBWP_ToAddModList->list.count); + mac->DLbwp[0] = mac->scd->downlinkBWP_ToAddModList->list.array[0]; + AssertFatal(mac->DLbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n"); + AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config!=NULL,"pdcch_Config is null\n"); + AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL,"controlResourceSetToAddModList is null\n"); + AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count==1,"controlResourceSetToAddModList->list.count=%d\n", + mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count); + mac->coreset[0][0] = mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[0]; + AssertFatal(mac->coreset[0][0]!=NULL,"coreset[0][0] is null\n"); + + AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); + NR_SearchSpace_t *ss; + int ss_id=0; + AssertFatal(mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.countDLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count); + for (int i=0;iDLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { + ss=mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; + AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); + AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); + AssertFatal(*ss->controlResourceSetId == mac->coreset[0][0]->controlResourceSetId,"ss->controlResourceSetId is unknown\n"); + mac->SSpace[0][0][ss_id] = ss; + ss_id++; + } + } + if (mac->ULbwp[0]==NULL) { + AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList!=NULL,"uplinkBWP_ToAddModList is null\n"); + AssertFatal(mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count==1,"uplinkBWP_ToAddModList->list->count is %d\n", + mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.count); + mac->ULbwp[0] = mac->scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]; + AssertFatal(mac->ULbwp[0]->bwp_Dedicated!=NULL,"bwp_Dedicated is null\n"); + } + // check search spaces + + int ss_id=0; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + int sps =mac->DLbwp[0]->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; + + while(mac->SSpace[0][0][ss_id]!=NULL && + ss_id < mac->DLbwp[0]->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count) { + + AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n"); + AssertFatal(mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n"); + + ss_id++; + } + if (mac->ra_state == WAIT_RAR) { + // check for RAR + rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; + rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot); + dl_config->number_pdus = dl_config->number_pdus + 1; + } + else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION) { + rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; + rel15->rnti = mac->t_crnti; + dl_config->number_pdus = dl_config->number_pdus + 1; + } + if (mac->crnti>0) { + rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; + rel15->rnti = mac->crnti; + rel15->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + rel15->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + rel15->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + // get UE-specific search space + for (ss_id=0;ss_idSSpace[0][0][ss_id]!=NULL;ss_id++) + if (mac->SSpace[0][0][ss_id]->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break; + AssertFatal(ss_idSSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | + (mac->SSpace[0][0][ss_id]->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + + for (int i=0; i>(sps-1-i))&1) { + rel15->coreset.StartSymbolIndex=i; + break; + } + rel15->coreset.duration = mac->coreset[0][0]->duration; + for (int i=0;i<6;i++) + rel15->coreset.frequency_domain_resource[i] = mac->coreset[0][0]->frequencyDomainResources.buf[i]; + + rel15->coreset.CceRegMappingType = mac->coreset[0][0]->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved? + FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; + if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) { + rel15->coreset.RegBundleSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->reg_BundleSize); + rel15->coreset.InterleaverSize = (mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->interleaverSize); + AssertFatal(mac->scc->physCellId != NULL,"mac->scc->physCellId is null\n"); + rel15->coreset.ShiftIndex = mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *mac->coreset[0][0]->cce_REG_MappingType.choice.interleaved->shiftIndex : *mac->scc->physCellId; + } + else { + rel15->coreset.RegBundleSize = 0; + rel15->coreset.InterleaverSize = 0; + rel15->coreset.ShiftIndex = 0; + } + rel15->coreset.CoreSetType = 1; + rel15->coreset.precoder_granularity = mac->coreset[0][0]->precoderGranularity; + if (mac->coreset[0][0]->pdcch_DMRS_ScramblingID) + rel15->coreset.pdcch_dmrs_scrambling_id = *mac->coreset[0][0]->pdcch_DMRS_ScramblingID; + else + rel15->coreset.pdcch_dmrs_scrambling_id = *mac->scc->physCellId; + fill_dci_search_candidates(mac->SSpace[0][0][ss_id],rel15); + rel15->dci_format = NR_DL_DCI_FORMAT_1_0; + rel15->dci_length = nr_dci_size(rel15->dci_format,NR_RNTI_C,rel15->BWPSize); + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; + dl_config->number_pdus = dl_config->number_pdus + 1; + } + } +} + + + + diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index c573017140..ee09bb4eb4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -36,10 +36,31 @@ #include "assertions.h" #include "PHY/defs_nr_UE.h" #include "common/utils/LOG/log.h" +#include "mac_defs.h" +#include "../MAC/mac.h" +#include "../NR_MAC_gNB/nr_mac_common.h" +#include "common/utils/nr/nr_common.h" #include #include +//#define ENABLE_MAC_PAYLOAD_DEBUG 1 +#define DEBUG_EXTRACT_DCI 1 + +extern void mac_rlc_data_ind ( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + char *buffer_pP, + const tb_size_t tb_sizeP, + num_tb_t num_tbP, + crc_t *crcs_pP); + + uint32_t get_ssb_slot(uint32_t ssb_index){ // this function now only support f <= 3GHz return ssb_index & 0x3 ; @@ -79,11 +100,11 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, //ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.rnti = rnti; // First we need to verify if DCI ind contains a ul-sch to be perfomred. If it does, we will handle a PUSCH in the UL_CONFIG_REQ. - - /* ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUCCH; for (int i=0; i<10; i++) { - if (dci_ind->dci_list[i].dci_format < 2) ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; + if(dci_ind!=NULL){ + if (dci_ind->dci_list[i].dci_format < 2) ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; + } } if (ul_config->ul_config_list[ul_config->number_pdus].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { // fill in the elements in config request inside P5 message @@ -113,15 +134,15 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, } else { // If DCI ind is not format 0_0 or 0_1, we will handle a PUCCH in the UL_CONFIG_REQ ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUCCH; // If we handle PUCCH common - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.format = table_9_2_2_1[phy_config->config_req.pucch_config.pucch_resource_common][0]; // format 0 1 2 3 4 - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.initialCyclicShift = table_9_2_2_1[phy_config->config_req.pucch_config.pucch_resource_common][4]; // x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSymbols = table_9_2_2_1[phy_config->config_req.pucch_config.pucch_resource_common][2]; // x x x x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingSymbolIndex = table_9_2_2_1[phy_config->config_req.pucch_config.pucch_resource_common][1]; // x x x x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.timeDomainOCC = 0; // x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofPRBs = 0; // x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingPRB = table_9_2_2_1[phy_config->config_req.pucch_config.pucch_resource_common][3]; // maxNrofPhysicalResourceBlocks = 275 - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_length = 0; // x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_Index = 0; // x + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.format = table_9_2_2_1[phy_config->config_req.ul_bwp_common.pucch_config_common.pucch_resource_common][0]; /* format 0 1 2 3 4 */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.initialCyclicShift = table_9_2_2_1[phy_config->config_req.ul_bwp_common.pucch_config_common.pucch_resource_common][4]; /* x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSymbols = table_9_2_2_1[phy_config->config_req.ul_bwp_common.pucch_config_common.pucch_resource_common][2]; /* x x x x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingSymbolIndex = table_9_2_2_1[phy_config->config_req.ul_bwp_common.pucch_config_common.pucch_resource_common][1]; /* x x x x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.timeDomainOCC = 0; /* x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofPRBs = 0; /* x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingPRB = table_9_2_2_1[phy_config->config_req.ul_bwp_common.pucch_config_common.pucch_resource_common][3]; /* maxNrofPhysicalResourceBlocks = 275 */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_length = 0; /* x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_Index = 0; /* x */ ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.intraSlotFrequencyHopping = 0; ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.secondHopPRB = 0; ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.interslotFrequencyHopping = 0; @@ -130,17 +151,15 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSlots = 0; ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pi2PBSK = 0; ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.simultaneousHARQ_ACK_CSI = 0; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pucch_GroupHopping = phy_config->config_req.pucch_config.pucch_group_hopping; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.hoppingId = phy_config->config_req.pucch_config.hopping_id; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_nominal = phy_config->config_req.pucch_config.p0_nominal; - + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pucch_GroupHopping = phy_config->config_req.ul_bwp_common.pucch_config_common.pucch_group_hopping; + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.hoppingId = phy_config->config_req.ul_bwp_common.pucch_config_common.hopping_id; + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_nominal = phy_config->config_req.ul_bwp_common.pucch_config_common.p0_nominal; for (int i=0;iul_config_list[ul_config->number_pdus].pucch_config_pdu.deltaF_PUCCH_f[i] = 0; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_PUCCH_Id = 0; // INTEGER (1..8) + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_PUCCH_Id = 0; /* INTEGER (1..8) */ ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_PUCCH_Value = 0; ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.twoPUCCH_PC_AdjustmentStates = 0; - // If we handle PUCCH dedicated - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.format = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].format; // format 0 1 2 3 4 + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.format = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].format; /* format 0 1 2 3 4 */ switch (ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.format){ case pucch_format1_nr: ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.interslotFrequencyHopping = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format1.inter_slot_frequency_hopping; @@ -177,27 +196,25 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, default: break; } - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.initialCyclicShift = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].initial_cyclic_shift; // x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSymbols = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].number_of_symbols; // x x x x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingSymbolIndex = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].starting_symbol_index; // x x x x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.timeDomainOCC = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].time_domain_occ; // x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofPRBs = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].number_of_prbs; // x x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingPRB = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].starting_prb; // maxNrofPhysicalResourceBlocks = 275 - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_length = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].occ_length; // x - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_Index = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].occ_index; // x + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.initialCyclicShift = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].initial_cyclic_shift; /* x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSymbols = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].number_of_symbols; /* x x x x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingSymbolIndex = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].starting_symbol_index; /* x x x x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.timeDomainOCC = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].time_domain_occ; /* x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofPRBs = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].number_of_prbs; /* x x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.startingPRB = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].starting_prb; /* maxNrofPhysicalResourceBlocks = 275 */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_length = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].occ_length; /* x */ + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.occ_Index = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].occ_index; /* x */ ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.intraSlotFrequencyHopping = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].intra_slot_frequency_hopping; ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.secondHopPRB = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.multi_csi_pucch_resources[0].second_hop_prb; - - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pucch_GroupHopping = phy_config->config_req.pucch_config.pucch_group_hopping; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.hoppingId = phy_config->config_req.pucch_config.hopping_id; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_nominal = phy_config->config_req.pucch_config.p0_nominal; + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pucch_GroupHopping = phy_config->config_req.ul_bwp_common.pucch_config_common.pucch_group_hopping; + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.hoppingId = phy_config->config_req.ul_bwp_common.pucch_config_common.hopping_id; + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_nominal = phy_config->config_req.ul_bwp_common.pucch_config_common.p0_nominal; for (int i=0;iul_config_list[ul_config->number_pdus].pucch_config_pdu.deltaF_PUCCH_f[i] = 0; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_PUCCH_Id = 0; // INTEGER (1..8) + ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_PUCCH_Id = 0; /* INTEGER (1..8) */ ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.p0_PUCCH_Value = 0; ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.twoPUCCH_PC_AdjustmentStates = 0; } - */ if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ mac->if_module->scheduled_response(&mac->scheduled_response); } @@ -215,7 +232,7 @@ int8_t nr_ue_decode_mib( void *pduP, uint16_t cell_id ){ - LOG_I(MAC,"[L2][MAC] decode mib\n"); + LOG_D(MAC,"[L2][MAC] decode mib\n"); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -270,17 +287,12 @@ int8_t nr_ue_decode_mib( scs_pdcch = scs_30kHz; } - channel_bandwidth_t min_channel_bw = bw_40MHz; // deafult for testing + channel_bandwidth_t min_channel_bw = bw_10MHz; // deafult for testing uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13 frequency_range_t frequency_range = FR1; -#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0)) uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1.controlResourceSetZero); uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1.searchSpaceZero); -#else - uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1 >> 4) & 0xf; - uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1 & 0xf); -#endif int32_t num_rbs = -1; int32_t num_symbols = -1; int32_t rb_offset = -1; @@ -394,6 +406,7 @@ int8_t nr_ue_decode_mib( }else{ rb_offset = table_38213_13_10_c4[index_4msb]; } + break; default: @@ -415,27 +428,28 @@ int8_t nr_ue_decode_mib( mask = mask | 0x100000000000; } //LOG_I(MAC,">>>>>>>>mask %x num_rbs %d rb_offset %d\n", mask, num_rbs, rb_offset); - mac->type0_pdcch_dci_config.coreset.frequency_domain_resource = mask; - mac->type0_pdcch_dci_config.coreset.rb_offset = rb_offset; // additional parameter other than coreset - - //mac->type0_pdcch_dci_config.type0_pdcch_coreset.duration = num_symbols; - mac->type0_pdcch_dci_config.coreset.cce_reg_mapping_type = CCE_REG_MAPPING_TYPE_INTERLEAVED; - mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_reg_bundle_size = 6; // L 38.211 7.3.2.2 - mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_interleaver_size = 2; // R 38.211 7.3.2.2 - mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_shift_index = cell_id; - mac->type0_pdcch_dci_config.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; - mac->type0_pdcch_dci_config.coreset.pdcch_dmrs_scrambling_id = cell_id; + /* + mac->type0_pdcch_dci_config.coreset.frequency_domain_resource = mask; + mac->type0_pdcch_dci_config.coreset.rb_offset = rb_offset; // additional parameter other than coreset + //mac->type0_pdcch_dci_config.type0_pdcch_coreset.duration = num_symbols; + mac->type0_pdcch_dci_config.coreset.cce_reg_mapping_type = CCE_REG_MAPPING_TYPE_INTERLEAVED; + mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_reg_bundle_size = 6; // L 38.211 7.3.2.2 + mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_interleaver_size = 2; // R 38.211 7.3.2.2 + mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_shift_index = cell_id; + mac->type0_pdcch_dci_config.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE; + mac->type0_pdcch_dci_config.coreset.pdcch_dmrs_scrambling_id = cell_id; + */ // type0-pdcch search space float big_o; float big_m; uint32_t temp; - SFN_C_TYPE sfn_c; // only valid for mux=1 - uint32_t n_c; - uint32_t number_of_search_space_per_slot; - uint32_t first_symbol_index; + SFN_C_TYPE sfn_c=SFN_C_IMPOSSIBLE; // only valid for mux=1 + uint32_t n_c=UINT_MAX; + uint32_t number_of_search_space_per_slot=UINT_MAX; + uint32_t first_symbol_index=UINT_MAX; uint32_t search_space_duration; // element of search space uint32_t coreset_duration; // element of coreset @@ -573,28 +587,38 @@ int8_t nr_ue_decode_mib( search_space_duration = 1; } + AssertFatal(number_of_search_space_per_slot!=UINT_MAX,""); coreset_duration = num_symbols * number_of_search_space_per_slot; - - mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0]; - mac->type0_pdcch_dci_config.number_of_candidates[1] = table_38213_10_1_1_c2[1]; - mac->type0_pdcch_dci_config.number_of_candidates[2] = table_38213_10_1_1_c2[2]; // CCE aggregation level = 4 - mac->type0_pdcch_dci_config.number_of_candidates[3] = table_38213_10_1_1_c2[3]; // CCE aggregation level = 8 - mac->type0_pdcch_dci_config.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16 - mac->type0_pdcch_dci_config.duration = search_space_duration; - mac->type0_pdcch_dci_config.coreset.duration = coreset_duration; // coreset - mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff; - + /* + mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0]; + mac->type0_pdcch_dci_config.number_of_candidates[1] = table_38213_10_1_1_c2[1]; + mac->type0_pdcch_dci_config.number_of_candidates[2] = table_38213_10_1_1_c2[2]; // CCE aggregation level = 4 + mac->type0_pdcch_dci_config.number_of_candidates[3] = table_38213_10_1_1_c2[3]; // CCE aggregation level = 8 + mac->type0_pdcch_dci_config.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16 + mac->type0_pdcch_dci_config.duration = search_space_duration; + mac->type0_pdcch_dci_config.coreset.duration = coreset_duration; // coreset + AssertFatal(first_symbol_index!=UINT_MAX,""); + mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff; + */ + AssertFatal(sfn_c!=SFN_C_IMPOSSIBLE,""); + AssertFatal(n_c!=UINT_MAX,""); mac->type0_pdcch_ss_sfn_c = sfn_c; mac->type0_pdcch_ss_n_c = n_c; // fill in the elements in config request inside P5 message - - //mac->phy_config.config_req.pbch_config.system_frame_number = frame; // after calculation - mac->phy_config.config_req.rf_config.dl_subcarrierspacing = mac->mib->subCarrierSpacingCommon; - mac->phy_config.config_req.sch_config.ssb_subcarrier_offset = ssb_subcarrier_offset; // after calculation - mac->phy_config.config_req.pdsch_config.dmrs_TypeA_Position = mac->mib->dmrs_TypeA_Position; - mac->phy_config.config_req.pdcch_config.controlResourceSetZero = (mac->mib->pdcch_ConfigSIB1.controlResourceSetZero); - mac->phy_config.config_req.pdcch_config.searchSpaceZero = mac->mib->pdcch_ConfigSIB1.searchSpaceZero; + mac->phy_config.Mod_id = module_id; + mac->phy_config.CC_id = cc_id; + + mac->phy_config.config_req.pbch_config.system_frame_number = frame; // after calculation + mac->phy_config.config_req.pbch_config.subcarrier_spacing_common = mac->mib->subCarrierSpacingCommon; + mac->phy_config.config_req.pbch_config.ssb_subcarrier_offset = ssb_subcarrier_offset; // after calculation + mac->phy_config.config_req.pbch_config.dmrs_type_a_position = mac->mib->dmrs_TypeA_Position; + mac->phy_config.config_req.pbch_config.pdcch_config_sib1 = (mac->mib->pdcch_ConfigSIB1.controlResourceSetZero) * 16 + (mac->mib->pdcch_ConfigSIB1.searchSpaceZero); + mac->phy_config.config_req.pbch_config.cell_barred = mac->mib->cellBarred; + mac->phy_config.config_req.pbch_config.intra_frequency_reselection = mac->mib->intraFreqReselection; + mac->phy_config.config_req.pbch_config.half_frame_bit = half_frame_bit; + mac->phy_config.config_req.pbch_config.ssb_index = ssb_index; + mac->phy_config.config_req.config_mask |= FAPI_NR_CONFIG_REQUEST_MASK_PBCH; if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL){ mac->if_module->phy_config_request(&mac->phy_config); @@ -627,66 +651,80 @@ NR_UE_L2_STATE_t nr_ue_scheduler( uint32_t search_space_mask = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - - // check type0 from 38.213 13 - if(ssb_index != -1){ - - if(mac->type0_pdcch_ss_mux_pattern == 1){ - // 38.213 chapter 13 - if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration; - } - if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration; - } - } - if(mac->type0_pdcch_ss_mux_pattern == 2){ - // 38.213 Table 13-13, 13-14 - if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration; - } - } - if(mac->type0_pdcch_ss_mux_pattern == 3){ - // 38.213 Table 13-15 - if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.duration; - } - } - } fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - // Type0 PDCCH search space - if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){ - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1; - - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config; - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; + + // check type0 from 38.213 13 if we have no CellGroupConfig + if ( mac->scd == NULL) { + if( ssb_index != -1){ + + if(mac->type0_pdcch_ss_mux_pattern == 1){ + // 38.213 chapter 13 + if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + } + if(mac->type0_pdcch_ss_mux_pattern == 2){ + // 38.213 Table 13-13, 13-14 + if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + } + if(mac->type0_pdcch_ss_mux_pattern == 3){ + // 38.213 Table 13-15 + if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + } + } // ssb_index != -1 + + // Type0 PDCCH search space + if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){ + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1; + + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config; + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; + /* + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set + + LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n", + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti, + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP); + */ + dl_config->number_pdus = dl_config->number_pdus + 1; + } + } + else { // get PDCCH configuration(s) from SCGConfig + + + + + // get Coreset and SearchSpace Information from spCellConfigDedicated + + + /* - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set - - LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n", - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti, - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP); - */ - dl_config->number_pdus = dl_config->number_pdus + 1; - } - - if(search_space_mask & type0a_pdcch){ - } - - if(search_space_mask & type1_pdcch){ - } - - if(search_space_mask & type2_pdcch){ - } - - if(search_space_mask & type3_pdcch){ + if(search_space_mask & type0a_pdcch){ + } + + if(search_space_mask & type1_pdcch){ + } + + if(search_space_mask & type2_pdcch){ + } + + if(search_space_mask & type3_pdcch){ + } + */ } @@ -696,6 +734,574 @@ NR_UE_L2_STATE_t nr_ue_scheduler( return UE_CONNECTION_OK; } +#if 0 +uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, + uint8_t slot, + int p, + crc_scrambled_t crc_scrambled, + uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], + uint8_t format) { + LOG_DDD("crc_scrambled=%d, n_RB_ULBWP=%d, n_RB_DLBWP=%d\n",crc_scrambled,n_RB_ULBWP,n_RB_DLBWP); + /* + * function nr_dci_format_size calculates and returns the size in bits of a determined format + * it also returns an bi-dimensional array 'dci_fields_sizes' with x rows and y columns, where: + * x is the number of fields defined in TS 38.212 subclause 7.3.1 (Each field is mapped in the order in which it appears in the description in the specification) + * y is the number of formats + * e.g.: dci_fields_sizes[10][0] contains the size in bits of the field FREQ_DOM_RESOURCE_ASSIGNMENT_UL for format 0_0 + */ + // pdsch_config contains the PDSCH-Config IE is used to configure the UE specific PDSCH parameters (TS 38.331) + PDSCH_Config_t pdsch_config = ue->PDSCH_Config; + // pusch_config contains the PUSCH-Config IE is used to configure the UE specific PUSCH parameters (TS 38.331) + PUSCH_Config_t pusch_config = ue->pusch_config; + PUCCH_Config_t pucch_config_dedicated = ue->pucch_config_dedicated_nr[eNB_id]; + crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig = ue->crossCarrierSchedulingConfig; + dmrs_UplinkConfig_t dmrs_UplinkConfig = ue->dmrs_UplinkConfig; + dmrs_DownlinkConfig_t dmrs_DownlinkConfig = ue->dmrs_DownlinkConfig; + csi_MeasConfig_t csi_MeasConfig = ue->csi_MeasConfig; + PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig= ue->PUSCH_ServingCellConfig; + PDSCH_ServingCellConfig_t PDSCH_ServingCellConfig= ue->PDSCH_ServingCellConfig; + NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; + // 1 CARRIER_IN + // crossCarrierSchedulingConfig from higher layers, variable crossCarrierSchedulingConfig indicates if 'cross carrier scheduling' is enabled or not: + // if No cross carrier scheduling: number of bits for CARRIER_IND is 0 + // if Cross carrier scheduling: number of bits for CARRIER_IND is 3 + // The IE CrossCarrierSchedulingConfig is used to specify the configuration when the cross-carrier scheduling is used in a cell + uint8_t crossCarrierSchedulingConfig_ind = 0; + + if (crossCarrierSchedulingConfig.schedulingCellInfo.other.cif_InSchedulingCell !=0 ) crossCarrierSchedulingConfig_ind=1; + + // 2 SUL_IND_0_1, // 40 SRS_REQUEST, // 50 SUL_IND_0_0 + // UL/SUL indicator (TS 38.331, supplementary uplink is indicated in higher layer parameter ServCellAdd-SUL from IE ServingCellConfig and ServingCellConfigCommon): + // 0 bit for UEs not configured with SUL in the cell or UEs configured with SUL in the cell but only PUCCH carrier in the cell is configured for PUSCH transmission + // 1 bit for UEs configured with SUL in the cell as defined in Table 7.3.1.1.1-1 + // sul_ind indicates whether SUL is configured in cell or not + uint8_t sul_ind=ue->supplementaryUplink.supplementaryUplink; // this value will be 0 or 1 depending on higher layer parameter ServCellAdd-SUL. FIXME!!! + // 7 BANDWIDTH_PART_IND + // number of UL BWPs configured by higher layers + uint8_t n_UL_BWP_RRC=1; // initialized to 1 but it has to be initialized by higher layers FIXME!!! + n_UL_BWP_RRC = ((n_UL_BWP_RRC > 3)?n_UL_BWP_RRC:(n_UL_BWP_RRC+1)); + // number of DL BWPs configured by higher layers + uint8_t n_DL_BWP_RRC=1; // initialized to 1 but it has to be initialized by higher layers FIXME!!! + n_DL_BWP_RRC = ((n_DL_BWP_RRC > 3)?n_DL_BWP_RRC:(n_DL_BWP_RRC+1)); + // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL + // if format0_0, only resource allocation type 1 is allowed + // if format0_1, then resource allocation type 0 can be configured and N_RBG is defined in TS 38.214 subclause 6.1.2.2.1 + // for PUSCH hopping with resource allocation type 1 + // n_UL_hopping = 1 if the higher layer parameter frequencyHoppingOffsetLists contains two offset values + // n_UL_hopping = 2 if the higher layer parameter frequencyHoppingOffsetLists contains four offset values + uint8_t n_UL_hopping=pusch_config.n_frequencyHoppingOffsetLists; + + if (n_UL_hopping == 2) { + n_UL_hopping = 1; + } else if (n_UL_hopping == 4) { + n_UL_hopping = 2; + } else { + n_UL_hopping = 0; + } + + ul_resourceAllocation_t ul_resource_allocation_type = pusch_config.ul_resourceAllocation; + uint8_t ul_res_alloc_type_0 = 0; + uint8_t ul_res_alloc_type_1 = 0; + + if (ul_resource_allocation_type == ul_resourceAllocationType0) ul_res_alloc_type_0 = 1; + + if (ul_resource_allocation_type == ul_resourceAllocationType1) ul_res_alloc_type_1 = 1; + + if (ul_resource_allocation_type == ul_dynamicSwitch) { + ul_res_alloc_type_0 = 1; + ul_res_alloc_type_1 = 1; + } + + uint8_t n_bits_freq_dom_res_assign_ul=0,n_ul_RGB_tmp; + + if (ul_res_alloc_type_0 == 1) { // implementation of Table 6.1.2.2.1-1 TC 38.214 subclause 6.1.2.2.1 + // config1: PUSCH-Config IE contains rbg-Size ENUMERATED {config1 config2} + ul_rgb_Size_t config = pusch_config.ul_rgbSize; + uint8_t nominal_RBG_P = (config==ul_rgb_config1?2:4); + + if (n_RB_ULBWP > 36) nominal_RBG_P = (config==ul_rgb_config1?4:8); + + if (n_RB_ULBWP > 72) nominal_RBG_P = (config==ul_rgb_config1?8:16); + + if (n_RB_ULBWP > 144) nominal_RBG_P = 16; + + n_bits_freq_dom_res_assign_ul = (uint8_t)ceil((n_RB_ULBWP+(0%nominal_RBG_P))/nominal_RBG_P); //FIXME!!! what is 0??? + n_ul_RGB_tmp = n_bits_freq_dom_res_assign_ul; + } + + if (ul_res_alloc_type_1 == 1) n_bits_freq_dom_res_assign_ul = (uint8_t)(ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)))-n_UL_hopping; + + if ((ul_res_alloc_type_0 == 1) && (ul_res_alloc_type_1 == 1)) + n_bits_freq_dom_res_assign_ul = ((n_bits_freq_dom_res_assign_ul>n_ul_RGB_tmp)?(n_bits_freq_dom_res_assign_ul+1):(n_ul_RGB_tmp+1)); + + // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL + // if format1_0, only resource allocation type 1 is allowed + // if format1_1, then resource allocation type 0 can be configured and N_RBG is defined in TS 38.214 subclause 5.1.2.2.1 + dl_resourceAllocation_t dl_resource_allocation_type = pdsch_config.dl_resourceAllocation; + uint8_t dl_res_alloc_type_0 = 0; + uint8_t dl_res_alloc_type_1 = 0; + + if (dl_resource_allocation_type == dl_resourceAllocationType0) dl_res_alloc_type_0 = 1; + + if (dl_resource_allocation_type == dl_resourceAllocationType1) dl_res_alloc_type_1 = 1; + + if (dl_resource_allocation_type == dl_dynamicSwitch) { + dl_res_alloc_type_0 = 1; + dl_res_alloc_type_1 = 1; + } + + uint8_t n_bits_freq_dom_res_assign_dl=0,n_dl_RGB_tmp; + + if (dl_res_alloc_type_0 == 1) { // implementation of Table 5.1.2.2.1-1 TC 38.214 subclause 6.1.2.2.1 + // config1: PDSCH-Config IE contains rbg-Size ENUMERATED {config1, config2} + dl_rgb_Size_t config = pdsch_config.dl_rgbSize; + uint8_t nominal_RBG_P = (config==dl_rgb_config1?2:4); + + if (n_RB_DLBWP > 36) nominal_RBG_P = (config==dl_rgb_config1?4:8); + + if (n_RB_DLBWP > 72) nominal_RBG_P = (config==dl_rgb_config1?8:16); + + if (n_RB_DLBWP > 144) nominal_RBG_P = 16; + + n_bits_freq_dom_res_assign_dl = (uint8_t)ceil((n_RB_DLBWP+(0%nominal_RBG_P))/nominal_RBG_P); //FIXME!!! what is 0??? + n_dl_RGB_tmp = n_bits_freq_dom_res_assign_dl; + } + + if (dl_res_alloc_type_1 == 1) n_bits_freq_dom_res_assign_dl = (uint8_t)(ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2))); + + if ((dl_res_alloc_type_0 == 1) && (dl_res_alloc_type_1 == 1)) + n_bits_freq_dom_res_assign_dl = ((n_bits_freq_dom_res_assign_dl>n_dl_RGB_tmp)?(n_bits_freq_dom_res_assign_dl+1):(n_dl_RGB_tmp+1)); + + // 12 TIME_DOM_RESOURCE_ASSIGNMENT + uint8_t pusch_alloc_list = pusch_config.n_push_alloc_list; + uint8_t pdsch_alloc_list = pdsch_config.n_pdsh_alloc_list; + // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] + static_bundleSize_t static_prb_BundlingType = pdsch_config.prbBundleType.staticBundling; + bundleSizeSet1_t dynamic_prb_BundlingType1 = pdsch_config.prbBundleType.dynamicBundlig.bundleSizeSet1; + bundleSizeSet2_t dynamic_prb_BundlingType2 = pdsch_config.prbBundleType.dynamicBundlig.bundleSizeSet2; + uint8_t prb_BundlingType_size=0; + + if ((static_prb_BundlingType==st_n4)||(static_prb_BundlingType==st_wideband)) prb_BundlingType_size=0; + + if ((dynamic_prb_BundlingType1==dy_1_n4)||(dynamic_prb_BundlingType1==dy_1_wideband)||(dynamic_prb_BundlingType1==dy_1_n2_wideband)||(dynamic_prb_BundlingType1==dy_1_n4_wideband)|| + (dynamic_prb_BundlingType2==dy_2_n4)||(dynamic_prb_BundlingType2==dy_2_wideband)) prb_BundlingType_size=1; + + // 15 RATE_MATCHING_IND FIXME!!! + // according to TS 38.212: Rate matching indicator – 0, 1, or 2 bits according to higher layer parameter rateMatchPattern + uint8_t rateMatching_bits = pdsch_config.n_rateMatchPatterns; + // 16 ZP_CSI_RS_TRIGGER FIXME!!! + // 0, 1, or 2 bits as defined in Subclause 5.1.4.2 of [6, TS 38.214]. + // is the number of ZP CSI-RS resource sets in the higher layer parameter zp-CSI-RS-Resource + uint8_t n_zp_bits = pdsch_config.n_zp_CSI_RS_ResourceId; + // 17 FREQ_HOPPING_FLAG + // freqHopping is defined by higher layer parameter frequencyHopping from IE PUSCH-Config. Values are ENUMERATED{mode1, mode2} + frequencyHopping_t f_hopping = pusch_config.frequencyHopping; + uint8_t freqHopping = 0; + + if ((f_hopping==f_hop_mode1)||(f_hopping==f_hop_mode2)) freqHopping = 1; + + // 28 DAI + pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook = pdsch_config.pdsch_HARQ_ACK_Codebook; + uint8_t n_dai = 0; + uint8_t n_serving_cell_dl = 1; // this is hardcoded to 1 as we need to get this value from RRC higher layers parameters. FIXME!!! + + if ((pdsch_HARQ_ACK_Codebook == dynamic) && (n_serving_cell_dl == 1)) n_dai = 2; + + if ((pdsch_HARQ_ACK_Codebook == dynamic) && (n_serving_cell_dl > 1)) n_dai = 4; + + // 29 FIRST_DAI + uint8_t codebook_HARQ_ACK = 0; // We need to get this value to calculate number of bits of fields 1st DAI and 2nd DAI. + + if (pdsch_HARQ_ACK_Codebook == semiStatic) codebook_HARQ_ACK = 1; + + if (pdsch_HARQ_ACK_Codebook == dynamic) codebook_HARQ_ACK = 2; + + // 30 SECOND_DAI + uint8_t n_HARQ_ACK_sub_codebooks = 0; // We need to get this value to calculate number of bits of fields 1st DAI and 2nd DAI. FIXME!!! + // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND + uint8_t pdsch_harq_t_ind = (uint8_t)ceil(log2(pucch_config_dedicated.dl_DataToUL_ACK[0])); + // 36 SRS_RESOURCE_IND + // n_SRS is the number of configured SRS resources in the SRS resource set associated with the higher layer parameter usage of value 'codeBook' or 'nonCodeBook' + // from SRS_ResourceSet_t type we should get the information of the usage parameter (with possible values beamManagement, codebook, nonCodebook, antennaSwitching) + // at frame_parms->srs_nr->p_SRS_ResourceSetList[]->usage + uint8_t n_SRS = ue->srs.number_srs_Resource_Set; + // 37 PRECOD_NBR_LAYERS + // 38 ANTENNA_PORTS + txConfig_t txConfig = pusch_config.txConfig; + transformPrecoder_t transformPrecoder = pusch_config.transformPrecoder; + codebookSubset_t codebookSubset = pusch_config.codebookSubset; + uint8_t maxRank = pusch_config.maxRank; + uint8_t num_antenna_ports = 1; // this is hardcoded. We need to get the real value FIXME!!! + uint8_t precond_nbr_layers_bits = 0; + uint8_t antenna_ports_bits_ul = 0; + + // searching number of bits at tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2 + if (txConfig == txConfig_codebook) { + if (num_antenna_ports == 4) { + if ((transformPrecoder == transformPrecoder_disabled) && ((maxRank == 2)||(maxRank == 3)||(maxRank == 4))) { // Table 7.3.1.1.2-2 + if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=6; + + if (codebookSubset == codebookSubset_partialAndNonCoherent) precond_nbr_layers_bits=5; + + if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=4; + } + + if (((transformPrecoder == transformPrecoder_enabled)||(transformPrecoder == transformPrecoder_disabled)) && (maxRank == 1)) { // Table 7.3.1.1.2-3 + if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=5; + + if (codebookSubset == codebookSubset_partialAndNonCoherent) precond_nbr_layers_bits=4; + + if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=2; + } + } + + if (num_antenna_ports == 2) { + if ((transformPrecoder == transformPrecoder_disabled) && (maxRank == 2)) { // Table 7.3.1.1.2-4 + if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=4; + + if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=2; + } + + if (((transformPrecoder == transformPrecoder_enabled)||(transformPrecoder == transformPrecoder_disabled)) && (maxRank == 1)) { // Table 7.3.1.1.2-5 + if (codebookSubset == codebookSubset_fullyAndPartialAndNonCoherent) precond_nbr_layers_bits=3; + + if (codebookSubset == codebookSubset_nonCoherent) precond_nbr_layers_bits=1; + } + } + } + + if (txConfig == txConfig_nonCodebook) { + } + + // searching number of bits at tables 7.3.1.1.2-6/7/8/9/10/11/12/13/14/15/16/17/18/19 + if((dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)) { + if ((transformPrecoder == transformPrecoder_enabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 2; + + if ((transformPrecoder == transformPrecoder_enabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 4; + + if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 3; + + if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 4; + } + + if((dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type2)) { + if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len1)) antenna_ports_bits_ul = 4; + + if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.pusch_maxLength == pusch_len2)) antenna_ports_bits_ul = 5; + } + + // for format 1_1 number of bits as defined by Tables 7.3.1.2.2-1/2/3/4 + uint8_t antenna_ports_bits_dl = 0; + + if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len1)) antenna_ports_bits_dl = 4; // Table 7.3.1.2.2-1 + + if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len2)) antenna_ports_bits_dl = 5; // Table 7.3.1.2.2-2 + + if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type2) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len1)) antenna_ports_bits_dl = 5; // Table 7.3.1.2.2-3 + + if((dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type2) && (dmrs_DownlinkConfig.pdsch_maxLength == pdsch_len2)) antenna_ports_bits_dl = 6; // Table 7.3.1.2.2-4 + + // 39 TCI + uint8_t tci_bits=0; + + if (pdcch_vars2->coreset[p].tciPresentInDCI == tciPresentInDCI_enabled) tci_bits=3; + + // 42 CSI_REQUEST + // reportTriggerSize is defined in the CSI-MeasConfig IE (TS 38.331). + // Size of CSI request field in DCI (bits). Corresponds to L1 parameter 'ReportTriggerSize' (see 38.214, section 5.2) + uint8_t reportTriggerSize = csi_MeasConfig.reportTriggerSize; // value from 0..6 + // 43 CBGTI + // for format 0_1 + uint8_t maxCodeBlockGroupsPerTransportBlock = 0; + + if (PUSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock != 0) + maxCodeBlockGroupsPerTransportBlock = (uint8_t)PUSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock; + + // for format 1_1, as defined in Subclause 5.1.7 of [6, TS38.214] + uint8_t maxCodeBlockGroupsPerTransportBlock_dl = 0; + + if (PDSCH_ServingCellConfig.maxCodeBlockGroupsPerTransportBlock_dl != 0) + maxCodeBlockGroupsPerTransportBlock_dl = pdsch_config.maxNrofCodeWordsScheduledByDCI; // FIXME!!! + + // 44 CBGFI + uint8_t cbgfi_bit = PDSCH_ServingCellConfig.codeBlockGroupFlushIndicator; + // 45 PTRS_DMRS + // 0 bit if PTRS-UplinkConfig is not configured and transformPrecoder=disabled, or if transformPrecoder=enabled, or if maxRank=1 + // 2 bits otherwise + uint8_t ptrs_dmrs_bits=0; //FIXME!!! + // 46 BETA_OFFSET_IND + // at IE PUSCH-Config, beta_offset indicator – 0 if the higher layer parameter betaOffsets = semiStatic; otherwise 2 bits + // uci-OnPUSCH + // Selection between and configuration of dynamic and semi-static beta-offset. If the field is absent or released, the UE applies the value 'semiStatic' and the BetaOffsets + uint8_t betaOffsets = 0; + + if (pusch_config.uci_onPusch.betaOffset_type == betaOffset_semiStatic); + + if (pusch_config.uci_onPusch.betaOffset_type == betaOffset_dynamic) betaOffsets = 2; + + // 47 DMRS_SEQ_INI + uint8_t dmrs_seq_ini_bits_ul = 0; + uint8_t dmrs_seq_ini_bits_dl = 0; + + //1 bit if both scramblingID0 and scramblingID1 are configured in DMRS-UplinkConfig + if ((transformPrecoder == transformPrecoder_disabled) && (dmrs_UplinkConfig.scramblingID0 != 0) && (dmrs_UplinkConfig.scramblingID1 != 0)) dmrs_seq_ini_bits_ul = 1; + + //1 bit if both scramblingID0 and scramblingID1 are configured in DMRS-DownlinkConfig + if ((dmrs_DownlinkConfig.scramblingID0 != 0) && (dmrs_DownlinkConfig.scramblingID0 != 0)) dmrs_seq_ini_bits_dl = 1; + + /* + * For format 2_2 + * + * This format supports power control commands for semi-persistent scheduling. + * As we can already support power control commands dynamically with formats 0_0/0_1 (TPC PUSCH) and 1_0/1_1 (TPC PUCCH) + * + * This format will be implemented in the future FIXME!!! + * + */ + // 5 BLOCK_NUMBER: The parameter tpc-PUSCH or tpc-PUCCH provided by higher layers determines the index to the block number for an UL of a cell + // The following fields are defined for each block: Closed loop indicator and TPC command + // 6 CLOSE_LOOP_IND + // 41 TPC_CMD + uint8_t tpc_cmd_bit_2_2 = 2; + /* + * For format 2_3 + * + * This format is used for power control of uplink sounding reference signals for devices which have not coupled SRS power control to the PUSCH power control + * either because independent control is desirable or because the device is configured without PUCCH and PUSCH + * + * This format will be implemented in the future FIXME!!! + * + */ + // 40 SRS_REQUEST + // 41 TPC_CMD + uint8_t tpc_cmd_bit_2_3 = 0; + uint8_t dci_field_size_table [NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = { // This table contains the number of bits for each field (row) contained in each dci format (column). + // The values of the variables indicate field sizes in number of bits + //Format0_0 Format0_1 Format1_0 Format1_1 Formats2_0/1/2/3 + { + 1, 1, (((crc_scrambled == _p_rnti) || (crc_scrambled == _si_rnti) || (crc_scrambled == _ra_rnti)) ? 0:1), + 1, 0,0,0,0 + }, // 0 IDENTIFIER_DCI_FORMATS: + { + 0, ((crossCarrierSchedulingConfig_ind == 0) ? 0:3), + 0, ((crossCarrierSchedulingConfig_ind == 0) ? 0:3), + 0,0,0,0 + }, // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] + {0, (sul_ind == 0)?0:1, 0, 0, 0,0,0,0}, // 2 SUL_IND_0_1: + {0, 0, 0, 0, 1,0,0,0}, // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] + {0, 0, 0, 0, 0,1,0,0}, // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits + {0, 0, 0, 0, 0,0,0,0}, // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3 + {0, 0, 0, 0, 0,0,1,0}, // 6 CLOSE_LOOP_IND + { + 0, (uint8_t)ceil(log2(n_UL_BWP_RRC)), + 0, (uint8_t)ceil(log2(n_DL_BWP_RRC)), + 0,0,0,0 + }, // 7 BANDWIDTH_PART_IND: + { + 0, 0, ((crc_scrambled == _p_rnti) ? 2:0), + 0, 0,0,0,0 + }, // 8 SHORT_MESSAGE_IND 2 bits if crc scrambled with P-RNTI + { + 0, 0, ((crc_scrambled == _p_rnti) ? 8:0), + 0, 0,0,0,0 + }, // 9 SHORT_MESSAGES 8 bit8 if crc scrambled with P-RNTI + { + (uint8_t)(ceil(log2(n_RB_ULBWP*(n_RB_ULBWP+1)/2)))-n_UL_hopping, + n_bits_freq_dom_res_assign_ul, + 0, 0, 0,0,0,0 + }, // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered + // (NOTE 1) If DCI format 0_0 is monitored in common search space + // and if the number of information bits in the DCI format 0_0 prior to padding + // is larger than the payload size of the DCI format 1_0 monitored in common search space + // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 + // is reduced such that the size of DCI format 0_0 equals to the size of the DCI format 1_0 + { + 0, 0, (uint8_t)ceil(log2(n_RB_DLBWP*(n_RB_DLBWP+1)/2)), + n_bits_freq_dom_res_assign_dl, + 0,0,0,0 + }, // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + { + 4, (uint8_t)log2(pusch_alloc_list), + 4, (uint8_t)log2(pdsch_alloc_list), + 0,0,0,0 + }, // 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + // where I the number of entries in the higher layer parameter pusch-AllocationList + { + 0, 0, 1, (((dl_res_alloc_type_0==1) &&(dl_res_alloc_type_1==0))?0:1), + 0,0,0,0 + }, // 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + {0, 0, 0, prb_BundlingType_size, 0,0,0,0}, // 14 PRB_BUNDLING_SIZE_IND:0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] + {0, 0, 0, rateMatching_bits, 0,0,0,0}, // 15 RATE_MATCHING_IND: 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set + {0, 0, 0, n_zp_bits, 0,0,0,0}, // 16 ZP_CSI_RS_TRIGGER: + { + 1, (((ul_res_alloc_type_0==1) &&(ul_res_alloc_type_1==0))||(freqHopping == 0))?0:1, + 0, 0, 0,0,0,0 + }, // 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 + {0, 0, 0, 5, 0,0,0,0}, // 18 TB1_MCS: + {0, 0, 0, 1, 0,0,0,0}, // 19 TB1_NDI: + {0, 0, 0, 2, 0,0,0,0}, // 20 TB1_RV: + {0, 0, 0, 5, 0,0,0,0}, // 21 TB2_MCS: + {0, 0, 0, 1, 0,0,0,0}, // 22 TB2_NDI: + {0, 0, 0, 2, 0,0,0,0}, // 23 TB2_RV: + {5, 5, 5, 0, 0,0,0,0}, // 24 MCS: + {1, 1, (crc_scrambled == _c_rnti)?1:0,0, 0,0,0,0}, // 25 NDI: + { + 2, 2, (((crc_scrambled == _c_rnti) || (crc_scrambled == _si_rnti)) ? 2:0), + 0, 0,0,0,0 + }, // 26 RV: + {4, 4, (crc_scrambled == _c_rnti)?4:0,4, 0,0,0,0}, // 27 HARQ_PROCESS_NUMBER: + {0, 0, (crc_scrambled == _c_rnti)?2:0,n_dai, 0,0,0,0}, // 28 DAI: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI + // 0 otherwise + {0, codebook_HARQ_ACK, 0, 0, 0,0,0,0}, // 29 FIRST_DAI: (1 or 2 bits) 1 bit for semi-static HARQ-ACK // 2 bits for dynamic HARQ-ACK codebook with single HARQ-ACK codebook + { + 0, (((codebook_HARQ_ACK == 2) &&(n_HARQ_ACK_sub_codebooks==2))?2:0), + 0, 0, 0,0,0,0 + }, // 30 SECOND_DAI: (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks // 0 bits otherwise + { + 0, 0, (((crc_scrambled == _p_rnti) || (crc_scrambled == _ra_rnti)) ? 2:0), + 0, 0,0,0,0 + }, // 31 TB_SCALING + {2, 2, 0, 0, 0,0,0,0}, // 32 TPC_PUSCH: + {0, 0, (crc_scrambled == _c_rnti)?2:0,2, 0,0,0,0}, // 33 TPC_PUCCH: + {0, 0, (crc_scrambled == _c_rnti)?3:0,3, 0,0,0,0}, // 34 PUCCH_RESOURCE_IND: + {0, 0, (crc_scrambled == _c_rnti)?3:0,pdsch_harq_t_ind, 0,0,0,0}, // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: + {0, (uint8_t)log2(n_SRS), 0, 0, 0,0,0,0}, // 36 SRS_RESOURCE_IND: + {0, precond_nbr_layers_bits, 0, 0, 0,0,0,0}, // 37 PRECOD_NBR_LAYERS: + {0, antenna_ports_bits_ul, 0, antenna_ports_bits_dl, 0,0,0,0}, // 38 ANTENNA_PORTS: + {0, 0, 0, tci_bits, 0,0,0,0}, // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits + {0, (sul_ind == 0)?2:3, 0, (sul_ind == 0)?2:3, 0,0,0,2}, // 40 SRS_REQUEST: + { + 0, 0, 0, 0, 0,0,tpc_cmd_bit_2_2, + tpc_cmd_bit_2_3 + }, + // 41 TPC_CMD: + {0, reportTriggerSize, 0, 0, 0,0,0,0}, // 42 CSI_REQUEST: + { + 0, maxCodeBlockGroupsPerTransportBlock, + 0, maxCodeBlockGroupsPerTransportBlock_dl, + 0,0,0,0 + }, // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH + {0, 0, 0, cbgfi_bit, 0,0,0,0}, // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator + {0, ptrs_dmrs_bits, 0, 0, 0,0,0,0}, // 45 PTRS_DMRS: + {0, betaOffsets, 0, 0, 0,0,0,0}, // 46 BETA_OFFSET_IND: + {0, dmrs_seq_ini_bits_ul, 0, dmrs_seq_ini_bits_dl, 0,0,0,0}, // 47 DMRS_SEQ_INI: 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding + // is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise + {0, 1, 0, 0, 0,0,0,0}, // 48 UL_SCH_IND: value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH + {0, 0, 0, 0, 0,0,0,0}, // 49 PADDING_NR_DCI: + // (NOTE 2) If DCI format 0_0 is monitored in common search space + // and if the number of information bits in the DCI format 0_0 prior to padding + // is less than the payload size of the DCI format 1_0 monitored in common search space + // zeros shall be appended to the DCI format 0_0 + // until the payload size equals that of the DCI format 1_0 + {(sul_ind == 0)?0:1, 0, 0, 0, 0,0,0,0}, // 50 SUL_IND_0_0: + {0, 0, 0, 0, 0,0,0,0}, // 51 RA_PREAMBLE_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) + {0, 0, 0, 0, 0,0,0,0}, // 52 SUL_IND_1_0 (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) + {0, 0, 0, 0, 0,0,0,0}, // 53 SS_PBCH_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) + {0, 0, 0, 0, 0,0,0,0}, // 54 PRACH_MASK_INDEX (random access procedure initiated by a PDCCH order not implemented, FIXME!!!) + { + 0, 0, ((crc_scrambled == _p_rnti)?6:(((crc_scrambled == _si_rnti) || (crc_scrambled == _ra_rnti))?16:0)), + 0, 0,0,0,0 + } // 55 RESERVED_NR_DCI + }; + // NOTE 1: adjustments in freq_dom_resource_assignment_UL to be done if necessary + // NOTE 2: adjustments in padding to be done if necessary + uint8_t dci_size [8] = {0,0,0,0,0,0,0,0}; // will contain size for each format + + for (int i=0 ; i position in table is 2) + dci_fields_sizes[j][i] = dci_field_size_table[j][i]; // dci_fields_sizes[j] contains the sizes of each field (j) for a determined format i + //} + } + + LOG_DDD("(nr_dci_format_size) dci_size[%d]=%d for n_RB_ULBWP=%d\n", + i,dci_size[i],n_RB_ULBWP); + } + + LOG_DDD("(nr_dci_format_size) dci_fields_sizes[][] = { \n"); + +#ifdef NR_PDCCH_DCI_DEBUG + for (int j=0; j dci_size[2])) { + dci_field_size_table[SUL_IND_0_0][0] = 0; + dci_size[0]=dci_size[0]-1; + } + + // if ((format == format0_0) || (format == format1_0)) { + // According to Section 7.3.1.1.1 in TS 38.212 + // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding + // is less than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell, + // zeros shall be appended to the DCI format 0_0 until the payload size equals that of the DCI format 1_0. + if (dci_size[0] < dci_size[2]) { // '0' corresponding to index for format0_0 and '2' corresponding to index of format1_0 + //if (format == format0_0) { + dci_fields_sizes[PADDING_NR_DCI][0] = dci_size[2] - dci_size[0]; + dci_size[0] = dci_size[2]; + LOG_DDD("(nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); + //} + } + + // If DCI format 0_0 is monitored in common search space and if the number of information bits in the DCI format 0_0 prior to padding + // is larger than the payload size of the DCI format 1_0 monitored in common search space for scheduling the same serving cell, + // the bitwidth of the frequency domain resource allocation field in the DCI format 0_0 is reduced + // such that the size of DCI format 0_0 equals to the size of the DCI format 1_0.. + if (dci_size[0] > dci_size[2]) { + //if (format == format0_0) { + dci_fields_sizes[FREQ_DOM_RESOURCE_ASSIGNMENT_UL][0] -= (dci_size[0] - dci_size[2]); + dci_size[0] = dci_size[2]; + LOG_DDD("(nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); + //} + } + + /* + * TS 38.212 subclause 7.3.1.1.2 + * For a UE configured with SUL in a cell: + * if PUSCH is configured to be transmitted on both the SUL and the non-SUL of the cell and + * if the number of information bits in format 0_1 for the SUL + * is not equal to the number of information bits in format 0_1 for the non-SUL, + * zeros shall be appended to smaller format 0_1 until the payload size equals that of the larger format 0_1 + * + * Not implemented. FIXME!!! + * + */ + // } + LOG_DDD("(nr_dci_format_size) dci_fields_sizes[][] = { \n"); + +#ifdef NR_PDCCH_DCI_DEBUG + for (int j=0; j floor (n_RB_DLBWP/2) - // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_DLBWP/2) - l_RB = floor(riv/n_RB_DLBWP) + 1; - start_RB = riv%n_RB_DLBWP; - // if (l_RB - 1) > floor (n_RB_DLBWP/2) we need to recalculate them using the following lines - tmp_RIV = n_RB_DLBWP * (l_RB - 1) + start_RB; - if ((tmp_RIV != riv) || ((start_RB+l_RB)>n_RB_DLBWP)) { // then (l_RB - 1) > floor (n_RB_DLBWP/2) and we need to recalculate l_RB and start_RB - l_RB = n_RB_DLBWP - l_RB + 2; - start_RB = n_RB_DLBWP - start_RB - 1; - } - dlsch_config_pdu->number_rbs = l_RB; - dlsch_config_pdu->start_rb = start_RB; + + dlsch_config_pdu->number_rbs = NRRIV2BW(riv,n_RB_DLBWP); + dlsch_config_pdu->start_rb = NRRIV2PRBOFFSET(riv,n_RB_DLBWP); + } if(ulsch_config_pdu != NULL){ /* @@ -1107,30 +1704,19 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment( /* * TS 38.214 subclause 6.1.2.2.2 Uplink resource allocation type 1 */ - // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): - // RIV = n_RB_ULBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_ULBWP/2) - // RIV = n_RB_ULBWP * (n_RB_ULBWP - l_RB + 1) + (n_RB_ULBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_ULBWP/2) - // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_ULBWP/2) - l_RB = floor(riv/n_RB_ULBWP) + 1; - start_RB = riv%n_RB_ULBWP; - // if (l_RB - 1) > floor (n_RB_ULBWP/2) we need to recalculate them using the following lines - tmp_RIV = n_RB_ULBWP * (l_RB - 1) + start_RB; - if (tmp_RIV != riv) { // then (l_RB - 1) > floor (n_RB_ULBWP/2) and we need to recalculate l_RB and start_RB - l_RB = n_RB_ULBWP - l_RB + 2; - start_RB = n_RB_ULBWP - start_RB - 1; - } - ulsch_config_pdu->number_rbs = l_RB; - ulsch_config_pdu->start_rb = start_RB; + + ulsch_config_pdu->number_rbs = NRRIV2BW(riv,n_RB_ULBWP); + ulsch_config_pdu->start_rb = NRRIV2PRBOFFSET(riv,n_RB_ULBWP); } return 0; } -int8_t nr_ue_process_dci_time_dom_resource_assignment( - fapi_nr_ul_config_ulsch_pdu_rel15_t *ulsch_config_pdu, +int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, + fapi_nr_ul_config_pusch_pdu_rel15_t *ulsch_config_pdu, fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, - uint8_t time_domain_ind, - long dmrs_typeA_pos //0=pos2,1=pos3 + uint8_t time_domain_ind ){ + int dmrs_typeA_pos = mac->scc->dmrs_TypeA_Position; uint8_t k_offset=0; uint8_t sliv_S=0; uint8_t sliv_L=0; @@ -1250,53 +1836,110 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment( * TS 38.214 subclause 5.1.2.1 Resource allocation in time domain (downlink) */ if(dlsch_config_pdu != NULL){ - k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; - sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; - sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; - // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - dlsch_config_pdu->frame_offset = k_offset; - dlsch_config_pdu->number_symbols = sliv_L; - dlsch_config_pdu->start_symbol = sliv_S; + NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL; + if (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList; + else if (mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + if (pdsch_TimeDomainAllocationList) { + + AssertFatal(pdsch_TimeDomainAllocationList->list.count > time_domain_ind, + "time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n", + time_domain_ind,pdsch_TimeDomainAllocationList->list.count); + int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength; + int S,L; + SLIV2SL(startSymbolAndLength,&S,&L); + dlsch_config_pdu->start_symbol=S; + dlsch_config_pdu->number_symbols=L; + dlsch_config_pdu->frame_offset = pdsch_TimeDomainAllocationList->list.array[time_domain_ind]->k0!=NULL ? + *pdsch_TimeDomainAllocationList->list.array[time_domain_ind]->k0 : + 0; + } + else {// Default configuration from tables + k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; + sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; + sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; + // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + // k_offset = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + // k_offset = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + dlsch_config_pdu->frame_offset = k_offset; + dlsch_config_pdu->number_symbols = sliv_L; + dlsch_config_pdu->start_symbol = sliv_S; + } } /* * TS 38.214 subclause 6.1.2.1 Resource allocation in time domain (uplink) */ if(ulsch_config_pdu != NULL){ - k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; - sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; - sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; - // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - ulsch_config_pdu->frame_offset = k_offset; - ulsch_config_pdu->number_symbols = sliv_L; - ulsch_config_pdu->start_symbol = sliv_S; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; + if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config) + pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->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); + int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength; + int S,L; + SLIV2SL(startSymbolAndLength,&S,&L); + ulsch_config_pdu->start_symbol=S; + ulsch_config_pdu->number_symbols=L; + ulsch_config_pdu->frame_offset = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2!=NULL ? + *pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2 : + mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing < NR_SubcarrierSpacing_kHz60 ? 1 : + mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing < NR_SubcarrierSpacing_kHz120 ? 2 : 3; + } + else { + k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; + sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1]; + sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2]; + // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + ulsch_config_pdu->frame_offset = k_offset; + ulsch_config_pdu->number_symbols = sliv_L; + ulsch_config_pdu->start_symbol = sliv_S; + } } return 0; } ////////////// +int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index,fapi_nr_dci_indication_pdu_t *dci) { -int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + nr_dci_pdu_rel15_t dci_pdu_rel15; + + 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,&dci_pdu_rel15); + nr_ue_process_dci(module_id, cc_id, gNB_index, &dci_pdu_rel15, dci->rnti, dci->dci_format); +} + +int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; //const uint16_t n_RB_DLBWP = dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP; //make sure this has been set - const uint16_t n_RB_DLBWP = mac->initial_bwp_dl.N_RB; - const uint16_t n_RB_ULBWP = mac->initial_bwp_ul.N_RB; + AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n"); + AssertFatal(mac->ULbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n"); - LOG_I(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); + const uint16_t n_RB_DLBWP = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + const uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + + 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; switch(dci_format){ - case format0_0: + case NR_UL_DCI_FORMAT_0_0: /* * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI * 0 IDENTIFIER_DCI_FORMATS: @@ -1311,19 +1954,21 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space * 50 SUL_IND_0_0: */ - ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.rnti = rnti; - fapi_nr_ul_config_ulsch_pdu_rel15_t *ulsch_config_pdu_0_0 = &ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15; + fapi_nr_ul_config_pusch_pdu_rel15_t *ulsch_config_pdu_0_0 = &ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15; /* IDENTIFIER_DCI_FORMATS */ /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ nr_ue_process_dci_freq_dom_resource_assignment(ulsch_config_pdu_0_0,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(ulsch_config_pdu_0_0,NULL,dci->time_dom_resource_assignment,mac->mib->dmrs_TypeA_Position); + nr_ue_process_dci_time_dom_resource_assignment(mac, + ulsch_config_pdu_0_0,NULL, + dci->time_dom_resource_assignment); + /* FREQ_HOPPING_FLAG */ - /* if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0)) - ulsch_config_pdu_0_0->pusch_freq_hopping = (dci->freq_hopping_flag == 0)? pusch_freq_hopping_disabled:pusch_freq_hopping_enabled;*/ + ulsch_config_pdu_0_0->pusch_freq_hopping = (dci->freq_hopping_flag == 0)? pusch_freq_hopping_disabled:pusch_freq_hopping_enabled; /* MCS */ ulsch_config_pdu_0_0->mcs = dci->mcs; /* NDI */ @@ -1355,7 +2000,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa ul_config->number_pdus = ul_config->number_pdus + 1; break; - case format0_1: + case NR_UL_DCI_FORMAT_0_1: /* * with CRC scrambled by C-RNTI or CS-RNTI or SP-CSI-RNTI or new-RNTI * 0 IDENTIFIER_DCI_FORMATS: @@ -1384,9 +2029,9 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa * 48 UL_SCH_IND * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space */ - ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.rnti = rnti; - fapi_nr_ul_config_ulsch_pdu_rel15_t *ulsch_config_pdu_0_1 = &ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15; + fapi_nr_ul_config_pusch_pdu_rel15_t *ulsch_config_pdu_0_1 = &ul_config->ul_config_list[ul_config->number_pdus].ulsch_config_pdu.ulsch_pdu_rel15; /* IDENTIFIER_DCI_FORMATS */ /* CARRIER_IND */ /* SUL_IND_0_1 */ @@ -1395,12 +2040,12 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ nr_ue_process_dci_freq_dom_resource_assignment(ulsch_config_pdu_0_1,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(ulsch_config_pdu_0_1,NULL,dci->time_dom_resource_assignment,mac->mib->dmrs_TypeA_Position); + nr_ue_process_dci_time_dom_resource_assignment(mac,ulsch_config_pdu_0_1,NULL, + dci->time_dom_resource_assignment); /* FREQ_HOPPING_FLAG */ - /* if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0)) - ulsch_config_pdu_0_1->pusch_freq_hopping = (dci->freq_hopping_flag == 0)? pusch_freq_hopping_disabled:pusch_freq_hopping_enabled;*/ + ulsch_config_pdu_0_1->pusch_freq_hopping = (dci->freq_hopping_flag == 0)? pusch_freq_hopping_disabled:pusch_freq_hopping_enabled; /* MCS */ ulsch_config_pdu_0_1->mcs = dci->mcs; /* NDI */ @@ -1432,7 +2077,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa /* SRS_RESOURCE_IND */ //FIXME!! /* PRECOD_NBR_LAYERS */ - /* if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.tx_config == tx_config_nonCodebook)); // 0 bits if the higher layer parameter txConfig = nonCodeBook if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.tx_config == tx_config_codebook)){ @@ -1503,11 +2147,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa } } } - */ /* ANTENNA_PORTS */ - uint8_t rank=0; // We need to initialize rank FIXME!!! - /* if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-6 @@ -1633,7 +2274,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa ulsch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports][5]; } } - */ /* SRS_REQUEST */ // if SUL is supported in the cell, there is an additional bit in thsi field and the value of this bit represents table 7.1.1.1-1 TS 38.212 FIXME!!! ulsch_config_pdu_0_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212 @@ -1642,7 +2282,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa /* CBGTI */ ulsch_config_pdu_0_1->maxCodeBlockGroupsPerTransportBlock = dci->cbgti; /* PTRS_DMRS */ - /* if (((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_disabled) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.ptrs_uplink_config == 0)) || ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.transform_precoder == transform_precoder_enabled) && @@ -1650,7 +2289,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa } else { ulsch_config_pdu_0_1->ptrs_dmrs_association_port = dci->ptrs_dmrs; } - */ /* BETA_OFFSET_IND */ // Table 9.3-3 in [5, TS 38.213] ulsch_config_pdu_0_1->beta_offset_ind = dci->beta_offset_ind; @@ -1663,7 +2301,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa ul_config->number_pdus = ul_config->number_pdus + 1; break; - case format1_0: + case NR_DL_DCI_FORMAT_1_0: /* * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI * 0 IDENTIFIER_DCI_FORMATS: @@ -1714,14 +2352,25 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI * 33 TPC_PUCCH: */ + dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; //fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config_pdu_1_0 = dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; /* IDENTIFIER_DCI_FORMATS */ /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,n_RB_DLBWP,dci->freq_dom_resource_assignment_DL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,dci->time_dom_resource_assignment,mac->mib->dmrs_TypeA_Position); + nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0, + dci->time_dom_resource_assignment); + + /* dmrs symbol positions*/ + dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, + mac->scc->dmrs_TypeA_Position, + dlsch_config_pdu_1_0->number_symbols); + dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 1 : 2; /* VRB_TO_PRB_MAPPING */ dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; /* MCS */ @@ -1783,14 +2432,14 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind); dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; + // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); dl_config->number_pdus = dl_config->number_pdus + 1; break; - case format1_1: + case NR_DL_DCI_FORMAT_1_1: /* * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI * 0 IDENTIFIER_DCI_FORMATS: @@ -1826,16 +2475,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa /* IDENTIFIER_DCI_FORMATS */ /* CARRIER_IND */ /* BANDWIDTH_PART_IND */ - dlsch_config_pdu_1_1->bandwidth_part_ind = dci->bandwidth_part_ind; + // dlsch_config_pdu_1_1->bandwidth_part_ind = dci->bandwidth_part_ind; /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,0,n_RB_DLBWP,dci->freq_dom_resource_assignment_DL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,dci->time_dom_resource_assignment,mac->mib->dmrs_TypeA_Position); + nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1, + dci->time_dom_resource_assignment); /* VRB_TO_PRB_MAPPING */ - /* if (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.resource_allocation != 0) dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; - */ /* PRB_BUNDLING_SIZE_IND */ dlsch_config_pdu_1_1->prb_bundling_size_ind = dci->prb_bundling_size_ind; /* RATE_MATCHING_IND */ @@ -1875,11 +2523,9 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa if (dci->pucch_resource_ind == 7) dlsch_config_pdu_1_1->pucch_resource_id = 0; //pucch-ResourceId obtained from the 8th value of resourceList FIXME!! /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */ // according to TS 38.213 Table 9.2.3-1 - /* - dlsch_config_pdu_1_1-> pdsch_to_harq_feedback_time_ind = mac->phy_config.config_req.ul_bwp_dedicated.pucch_config_dedicated.dl_data_to_ul_ack[dci->pdsch_to_harq_feedback_time_ind];*/ + dlsch_config_pdu_1_1-> pdsch_to_harq_feedback_time_ind = mac->phy_config.config_req.ul_bwp_dedicated.pucch_config_dedicated.dl_data_to_ul_ack[dci->pdsch_to_harq_feedback_time_ind]; /* ANTENNA_PORTS */ uint8_t n_codewords = 1; // FIXME!!! - /* if ((mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.dmrs_type == 1) && (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.dmrs_dl_for_pdsch_mapping_type_a.max_length == 1)){ // Table 7.3.1.2.2-1: Antenna port(s) (1000 + DMRS port), dmrs-Type=1, maxLength=1 @@ -1957,7 +2603,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports][9]; } } - */ /* TCI */ if (mac->dl_config_request.dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1){ // 0 bit if higher layer parameter tci-PresentInDCI is not enabled @@ -1974,7 +2619,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa /* DMRS_SEQ_INI */ //FIXME!!! - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; + // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); @@ -1983,16 +2628,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa break; - case format2_0: + case NR_DL_DCI_FORMAT_2_0: break; - case format2_1: + case NR_DL_DCI_FORMAT_2_1: break; - case format2_2: + case NR_DL_DCI_FORMAT_2_2: break; - case format2_3: + case NR_DL_DCI_FORMAT_2_3: break; default: @@ -2002,7 +2647,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fa if(rnti == SI_RNTI){ - }else if(rnti == mac->ra_rnti){ + // }else if(rnti == mac->ra_rnti){ }else if(rnti == P_RNTI){ @@ -2200,3 +2845,563 @@ void nr_ue_process_mac_pdu( AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n"); } } + +//--------------------------------------------------------------------------------- + + +unsigned char *parse_header(unsigned char *mac_header, + unsigned char *num_ce, + unsigned char *num_sdu, + unsigned char *rx_ces, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) +{ + + unsigned char not_done = 1, num_ces = 0, num_cont_res = + 0, num_padding = 0, num_sdus = 0, lcid, num_sdu_cnt; + unsigned char *mac_header_ptr = mac_header; + unsigned short length, ce_len = 0; + + while (not_done == 1) { + + if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { + // printf("E=0\n"); + not_done = 0; + } + + lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; + + if (lcid < UE_CONT_RES) { + //printf("[MAC][UE] header %x.%x.%x\n",mac_header_ptr[0],mac_header_ptr[1],mac_header_ptr[2]); + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = + tb_length - (mac_header_ptr - mac_header) - ce_len; + + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; + num_sdu_cnt++) { + length -= rx_lengths[num_sdu_cnt]; + } + } else { + if (((SCH_SUBHEADER_LONG *) mac_header_ptr)->F == 1) { + length = + ((((SCH_SUBHEADER_LONG *) mac_header_ptr)-> + L_MSB & 0x7f) + << 8) | (((SCH_SUBHEADER_LONG *) mac_header_ptr)-> + L_LSB & 0xff); + mac_header_ptr += 3; +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] parse long sdu, size %x \n", length); +#endif + + } else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; + } + } + +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] sdu %d lcid %d length %d (offset now %ld)\n", + num_sdus, lcid, length, mac_header_ptr - mac_header); +#endif + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } else { // This is a control element subheader + if (lcid == SHORT_PADDING) { + num_padding++; + mac_header_ptr++; + } else { + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; + + if (lcid == TIMING_ADV_CMD) { + ce_len++; + } else if (lcid == UE_CONT_RES) { + + // FNA: check MAC Header is one of thoses defined in Annex B of 36.321 + // Check there is only 1 Contention Resolution + if (num_cont_res) { + LOG_W(MAC, + "[UE] Msg4 Wrong received format: More than 1 Contention Resolution\n"); + // exit parsing + return NULL; + + } + // UE_CONT_RES shall never be the last subheader unless this is the only MAC subheader + if ((not_done == 0) + && ((num_sdus) || (num_ces > 1) || (num_padding))) { + LOG_W(MAC, + "[UE] Msg4 Wrong received format: Contention Resolution after num_ces=%d num_sdus=%d num_padding=%d\n", + num_ces, num_sdus, num_padding); + // exit parsing + return NULL; + } + num_cont_res++; + ce_len += 6; + } + } + +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] ce %d lcid %d (offset now %ld)\n", num_ces, + lcid, mac_header_ptr - mac_header); +#endif + } + } + + *num_ce = num_ces; + *num_sdu = num_sdus; + + return (mac_header_ptr); +} + + +//------------------------------------------------------------------------------ +void +nr_ue_send_sdu(module_id_t module_idP, + uint8_t CC_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index) +//------------------------------------------------------------------------------ +{ + + unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; + + + //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); + + + payload_ptr = + parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, + sdu_len); + +#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, + "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n", + module_idP, frameP, eNB_index, num_ce, num_sdu); +#endif + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + + for (i = 0; i < 32; i++) { + LOG_T(MAC, "%x.", sdu[i]); + } + + LOG_T(MAC, "\n"); +#endif + + if (payload_ptr != NULL) { + + for (i = 0; i < num_ce; i++) { + // printf("ce %d : %d\n",i,rx_ces[i]); + switch (rx_ces[i]) { + case UE_CONT_RES: + + break; + + case TIMING_ADV_CMD: + + break; + + case DRX_CMD: + + break; + } + } + + for (i = 0; i < num_sdu; i++) { +#ifdef DEBUG_HEADER_PARSING + LOG_I(MAC, "[UE] SDU %d : LCID %d, length %d\n", i, + rx_lcids[i], rx_lengths[i]); +#endif + if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1)) { + + LOG_D(MAC, + "[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", + module_idP, frameP, rx_lcids[i], eNB_index, + rx_lengths[i]); + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing MAC PDU contents at slot: %d \n", subframeP); + int j; + for (j = 0; j < 20; j++) //rx_lengths[i] + LOG_I(MAC, "%x.", (unsigned char) payload_ptr[j]); + LOG_I(MAC, "\n"); +#endif + mac_rlc_data_ind(module_idP, + 4660, //UE_mac_inst[module_idP].crnti //hardcode value corresponding to the one from the eNB + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + rx_lcids[i], + (char *) payload_ptr, rx_lengths[i], 1, + NULL); + } else { + LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (eNB %d)\n", + module_idP, frameP, rx_lcids[i], eNB_index); + } + payload_ptr += rx_lengths[i]; + } + } // end if (payload_ptr != NULL) + +} + + +int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, + int dci_format, + uint8_t dci_size, + uint16_t rnti, + uint64_t *dci_pdu, + nr_dci_pdu_rel15_t *dci_pdu_rel15) { + int rnti_type=-1; + + if (rnti == mac->ra_rnti) rnti_type = NR_RNTI_RA; + else if (rnti == mac->crnti) rnti_type = NR_RNTI_C; + else if (rnti == mac->t_crnti) rnti_type = NR_RNTI_TC; + else if (rnti == 0xFFFE) rnti_type = NR_RNTI_P; + else if (rnti == 0xFFFF) rnti_type = NR_RNTI_SI; + + 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->scd != NULL) ? + NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) : + NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275); + int N_RB_UL = (mac->scd != NULL) ? + NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) : + NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); + + int pos; + int fsize=0; + switch(dci_format) { + + case NR_DL_DCI_FORMAT_1_0: + switch(rnti_type) { + case NR_RNTI_RA: + // Freq domain assignment + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos=fsize; + dci_pdu_rel15->freq_dom_resource_assignment_DL = *dci_pdu>>(dci_size-pos)&((1< %d (0x%lx)\n",dci_pdu_rel15->freq_dom_resource_assignment_DL,fsize,N_RB,dci_size-pos,*dci_pdu); +#endif + // Time domain assignment + pos+=4; + dci_pdu_rel15->time_dom_resource_assignment = (*dci_pdu >> (dci_size-pos))&0xf; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_dom_resource_assignment,dci_size-pos,*dci_pdu); +#endif + // VRB to PRB mapping + + pos++; + dci_pdu_rel15->vrb_to_prb_mapping = (*dci_pdu>>(dci_size-pos))&0x1; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,dci_size-pos,*dci_pdu); +#endif + // MCS + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); +#endif + // TB scaling + pos+=2; + dci_pdu_rel15->tb_scaling = (*dci_pdu>>(dci_size-pos))&0x3; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); +#endif + break; + + case NR_RNTI_C: + + // indicating a DL DCI format 1bit + pos++; + dci_pdu_rel15->identifier_dci_formats = (*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->identifier_dci_formats,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; + dci_pdu_rel15->freq_dom_resource_assignment_DL = (*dci_pdu>>(dci_size-pos))&((1< %d (0x%lx)\n",dci_pdu_rel15->freq_dom_resource_assignment_DL,fsize,dci_size-pos,*dci_pdu); +#endif + + uint16_t is_ra = 1; + for (int i=0; ifreq_dom_resource_assignment_DL>>i)&1)) { + is_ra = 0; + break; + } + if (is_ra) //fsize are all 1 38.212 p86 + { + // ra_preamble_index 6 bits + pos+=6; + dci_pdu_rel15->ra_preamble_index = (*dci_pdu>>(dci_size-pos))&0x3f; + + // UL/SUL indicator 1 bit + pos++; + dci_pdu_rel15->sul_ind_0_1 = (*dci_pdu>>(dci_size-pos))&1; + + // SS/PBCH index 6 bits + pos+=6; + dci_pdu_rel15->ss_pbch_index = (*dci_pdu>>(dci_size-pos))&0x3f; + + // prach_mask_index 4 bits + pos+=4; + dci_pdu_rel15->prach_mask_index = (*dci_pdu>>(dci_size-pos))&0xf; + + } //end if + else { + + // Time domain assignment 4bit + + pos+=4; + dci_pdu_rel15->time_dom_resource_assignment = (*dci_pdu>>(dci_size-pos))&0xf; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_dom_resource_assignment,4,dci_size-pos,*dci_pdu); +#endif + + // VRB to PRB mapping 1bit + pos++; + dci_pdu_rel15->vrb_to_prb_mapping = (*dci_pdu>>(dci_size-pos))&1; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,1,dci_size-pos,*dci_pdu); +#endif + + // MCS 5bit //bit over 32, so dci_pdu ++ + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"MCS %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,5,dci_size-pos,*dci_pdu); +#endif + + // New data indicator 1bit + pos++; + dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); +#endif + + // Redundancy version 2bit + pos+=2; + dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); +#endif + + // HARQ process number 4bit + pos+=4; + dci_pdu_rel15->harq_process_number = (*dci_pdu>>(dci_size-pos))&0xf; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_process_number,4,dci_size-pos,*dci_pdu); +#endif + + // Downlink assignment index 2bit + pos+=2; + dci_pdu_rel15->dai = (*dci_pdu>>(dci_size-pos))&3; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"DAI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->dai,2,dci_size-pos,*dci_pdu); +#endif + + // TPC command for scheduled PUCCH 2bit + pos+=2; + dci_pdu_rel15->tpc_pucch = (*dci_pdu>>(dci_size-pos))&3; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc_pucch,2,dci_size-pos,*dci_pdu); +#endif + + // PUCCH resource indicator 3bit + pos+=3; + dci_pdu_rel15->pucch_resource_ind = (*dci_pdu>>(dci_size-pos))&0x7; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pucch_resource_ind,3,dci_size-pos,*dci_pdu); +#endif + + // PDSCH-to-HARQ_feedback timing indicator 3bit + pos+=3; + dci_pdu_rel15->pdsch_to_harq_feedback_time_ind = (*dci_pdu>>(dci_size-pos))&0x7; +#ifdef DEBUG_EXTRACT_DCI + LOG_D(MAC,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pdsch_to_harq_feedback_time_ind,3,dci_size-pos,*dci_pdu); +#endif + + } //end else + break; + + case NR_RNTI_P: + /* + // Short Messages Indicator – 2 bits + for (int i=0; i<2; i++) + dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_size-pos++); + // Short Messages – 8 bits + for (int i=0; i<8; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages>>(7-i))&1)<<(dci_size-pos++); + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4 bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos++); + // MCS 5 bit + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + + // TB scaling 2 bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_size-pos++); + */ + + break; + + case NR_RNTI_SI: + /* + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4 bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos++); + // MCS 5bit //bit over 32, so dci_pdu ++ + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + // Redundancy version 2bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++); + */ + break; + + case NR_RNTI_TC: + // indicating a DL DCI format 1bit + pos++; + dci_pdu_rel15->identifier_dci_formats = (*dci_pdu>>(dci_size-pos))&1; + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->freq_dom_resource_assignment_DL = (*dci_pdu>>(dci_size-pos))&((1<time_dom_resource_assignment = (*dci_pdu>>(dci_size-pos))&0xf; + // VRB to PRB mapping 1 bit + dci_pdu_rel15->vrb_to_prb_mapping = (*dci_pdu>>(dci_size-pos))&1; + // MCS 5bit //bit over 32, so dci_pdu ++ + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; + // New data indicator 1bit + 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_process_number = (*dci_pdu>>(dci_size-pos))&0xf; + // Downlink assignment index – 2 bits + pos+=2; + dci_pdu_rel15->dai = (*dci_pdu>>(dci_size-pos))&3; + // TPC command for scheduled PUCCH – 2 bits + pos+=2; + dci_pdu_rel15->tpc_pucch = (*dci_pdu>>(dci_size-pos))&3; + // PDSCH-to-HARQ_feedback timing indicator – 3 bits + pos+=3; + dci_pdu_rel15->pdsch_to_harq_feedback_time_ind = (*dci_pdu>>(dci_size-pos))&7; + + break; + } + break; + + case NR_UL_DCI_FORMAT_0_0: + switch(rnti_type) + { + case NR_RNTI_C: + // indicating a DL DCI format 1bit + dci_pdu_rel15->identifier_dci_formats = (*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->freq_dom_resource_assignment_UL = (*dci_pdu>>(dci_size-pos))&((1<time_dom_resource_assignment = (*dci_pdu>>(dci_size-pos))&0xf; + // Frequency hopping flag – 1 bit + pos++; + dci_pdu_rel15->freq_hopping_flag= (*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_process_number = (*dci_pdu>>(dci_size-pos))&0xf; + // TPC command for scheduled PUSCH – 2 bits + pos+=2; + dci_pdu_rel15->tpc_pusch = (*dci_pdu>>(dci_size-pos))&3; + // 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; + + case NR_RNTI_TC: + /* + // indicating a DL DCI format 1bit + dci_pdu->= (*dci_pdu>>(dci_size-pos)format_indicator&1)<<(dci_size-pos++); + // Freq domain assignment max 16 bit + fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); + for (int i=0; i= ((*dci_pdu>>(dci_size-pos)frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4bit + for (int i=0; i<4; i++) + dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // Frequency hopping flag – 1 bit + dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)frequency_hopping_flag&1)<<(dci_size-pos++); + // MCS 5 bit + for (int i=0; i<5; i++) + dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)mcs>>(4-i))&1)<<(dci_size-pos++); + // New data indicator 1bit + dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ndi&1)<<(dci_size-pos++); + // Redundancy version 2bit + for (int i=0; i<2; i++) + dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)rv>>(1-i))&1)<<(dci_size-pos++); + // HARQ process number 4bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)*dci_pdu>>(dci_size-pos)harq_pid>>(3-i))&1)<<(dci_size-pos++); + + // TPC command for scheduled PUSCH – 2 bits + for (int i=0; i<2; i++) + dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)tpc>>(1-i))&1)<<(dci_size-pos++); + */ + // UL/SUL indicator – 1 bit + /* + commented for now (RK): need to get this information from BWP descriptor + if (cfg->pucch_config.pucch_GroupHopping.value) + dci_pdu->= ((uint64_t)dci_pdu_rel15->ul_sul_indicator&1)<<(dci_size-pos++); + */ + break; + + } + break; + } +} + + diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index bcbb3822f6..d42c00f587 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -41,6 +41,7 @@ #include "NR_ServingCellConfigCommon.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "SCHED_NR/phy_frame_config_nr.h" #include "NR_MIB.h" @@ -49,125 +50,404 @@ extern RAN_CONTEXT_t RC; extern void mac_top_init_gNB(void); extern uint8_t nfapi_mode; +uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) +{ + uint16_t bandwidth; -void config_common(int Mod_idP, - NR_ServingCellConfigCommon_t *scc - ){ - nfapi_nr_config_request_t *cfg = &RC.nrmac[Mod_idP]->config[0]; - - int mu = 1; - - switch (*scc->ssb_periodicityServingCell) { - case 0: - cfg->sch_config.ssb_periodicity.value = 5; + if (nr_band < 100) { //FR1 + switch(mu) { + case 0 : + switch(nb_rb) { + case 25 : + bandwidth = 5; + break; + case 52 : + bandwidth = 10; + break; + case 79 : + bandwidth = 15; + break; + case 106 : + bandwidth = 20; + break; + case 133 : + bandwidth = 25; + break; + case 160 : + bandwidth = 30; + break; + case 216 : + bandwidth = 40; + break; + case 270 : + bandwidth = 50; + break; + default: + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d\n", nb_rb, mu); + } break; - case 1: - cfg->sch_config.ssb_periodicity.value = 10; + case 1 : + switch(nb_rb) { + case 11 : + bandwidth = 5; + break; + case 24 : + bandwidth = 10; + break; + case 38 : + bandwidth = 15; + break; + case 51 : + bandwidth = 20; + break; + case 65 : + bandwidth = 25; + break; + case 78 : + bandwidth = 30; + break; + case 106 : + bandwidth = 40; + break; + case 133 : + bandwidth = 50; + break; + case 162 : + bandwidth = 60; + break; + case 189 : + bandwidth = 70; + break; + case 217 : + bandwidth = 80; + break; + case 245 : + bandwidth = 90; + break; + case 273 : + bandwidth = 100; + break; + default: + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d\n", nb_rb, mu); + } break; - case 2: - cfg->sch_config.ssb_periodicity.value = 20; + case 2 : + switch(nb_rb) { + case 11 : + bandwidth = 10; + break; + case 18 : + bandwidth = 15; + break; + case 24 : + bandwidth = 20; + break; + case 31 : + bandwidth = 25; + break; + case 38 : + bandwidth = 30; + break; + case 51 : + bandwidth = 40; + break; + case 65 : + bandwidth = 50; + break; + case 79 : + bandwidth = 60; + break; + case 93 : + bandwidth = 70; + break; + case 107 : + bandwidth = 80; + break; + case 121 : + bandwidth = 90; + break; + case 135 : + bandwidth = 100; + break; + default: + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d\n", nb_rb, mu); + } break; - case 3: - cfg->sch_config.ssb_periodicity.value = 40; + default: + AssertFatal(1==0,"Numerology %d undefined for band %d in FR1\n", mu,nr_band); + } + } + else { + switch(mu) { + case 2 : + switch(nb_rb) { + case 66 : + bandwidth = 50; + break; + case 132 : + bandwidth = 100; + break; + case 264 : + bandwidth = 200; + break; + default: + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d\n", nb_rb, mu); + } break; - case 4: - cfg->sch_config.ssb_periodicity.value = 80; + case 3 : + switch(nb_rb) { + case 32 : + bandwidth = 50; + break; + case 66 : + bandwidth = 100; + break; + case 132 : + bandwidth = 200; + break; + case 264 : + bandwidth = 400; + break; + default: + AssertFatal(1==0,"Number of DL resource blocks %d undefined for mu %d\n", nb_rb, mu); + } break; - case 5: - cfg->sch_config.ssb_periodicity.value = 160; - break; - } + default: + AssertFatal(1==0,"Numerology %d undefined for band %d in FR1\n", mu,nr_band); + } + } + + return (bandwidth); +} - cfg->sch_config.physical_cell_id.value = *scc->physCellId; - cfg->sch_config.ssb_scg_position_in_burst.value = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]; - - // TDD - cfg->subframe_config.duplex_mode.value = 1; - cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; +void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { + + nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0]; + RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc; + int i; + + // Carrier configuration + + cfg->carrier_config.dl_bandwidth.value = config_bandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth, + *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]); + cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; //temporary cfg->num_tlv++; - - /// In NR DL and UL will be different band - cfg->nfapi_config.rf_bands.number_rf_bands = 1; - cfg->nfapi_config.rf_bands.rf_band[0] = *(long*)scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - cfg->nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; + LOG_I(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, cfg->carrier_config.dl_bandwidth.value); + + cfg->carrier_config.dl_frequency.value = from_nrarfcn(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA)/1000; // freq in kHz + cfg->carrier_config.dl_frequency.tl.tag = NFAPI_NR_CONFIG_DL_FREQUENCY_TAG; cfg->num_tlv++; - cfg->nfapi_config.nrarfcn.value = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + for (i=0; i<5; i++) { + if (i==scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { + cfg->carrier_config.dl_grid_size[i].value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + cfg->carrier_config.dl_k0[i].value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; + cfg->carrier_config.dl_grid_size[i].tl.tag = NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG; + cfg->carrier_config.dl_k0[i].tl.tag = NFAPI_NR_CONFIG_DL_K0_TAG; + cfg->num_tlv++; + cfg->num_tlv++; + } + else { + cfg->carrier_config.dl_grid_size[i].value = 0; + cfg->carrier_config.dl_k0[i].value = 0; + } + } - cfg->nfapi_config.nrarfcn.tl.tag = NFAPI_NR_NFAPI_NRARFCN_TAG; + cfg->carrier_config.uplink_bandwidth.value = config_bandwidth(scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth, + *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]); + cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; //temporary + cfg->num_tlv++; + LOG_I(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, cfg->carrier_config.uplink_bandwidth.value); + + int UL_pointA; + if (scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA == NULL) + UL_pointA = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + else + UL_pointA = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA; + + cfg->carrier_config.uplink_frequency.value = from_nrarfcn(*scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0], + UL_pointA)/1000; // freq in kHz + cfg->carrier_config.uplink_frequency.tl.tag = NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG; cfg->num_tlv++; - cfg->subframe_config.numerology_index_mu.value = mu; - //cfg->subframe_config.tl.tag = - //cfg->num_tlv++; - - cfg->rf_config.dl_carrier_bandwidth.value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - cfg->rf_config.dl_carrier_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; //temporary - cfg->num_tlv++; - LOG_I(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, cfg->rf_config.dl_carrier_bandwidth.value); - - cfg->rf_config.ul_carrier_bandwidth.value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - cfg->rf_config.ul_carrier_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; - cfg->num_tlv++; - - cfg->rf_config.dl_subcarrierspacing.value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - cfg->rf_config.dl_subcarrierspacing.tl.tag = NFAPI_NR_RF_CONFIG_DL_SUBCARRIERSPACING_TAG; - cfg->num_tlv++; - - cfg->rf_config.ul_subcarrierspacing.value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - cfg->rf_config.ul_subcarrierspacing.tl.tag = NFAPI_NR_RF_CONFIG_UL_SUBCARRIERSPACING_TAG; - cfg->num_tlv++; - - cfg->rf_config.dl_offsettocarrier.value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; - cfg->rf_config.dl_offsettocarrier.tl.tag = NFAPI_NR_RF_CONFIG_DL_OFFSETTOCARRIER_TAG; - cfg->num_tlv++; - - cfg->rf_config.ul_offsettocarrier.value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; - cfg->rf_config.ul_offsettocarrier.tl.tag = NFAPI_NR_RF_CONFIG_UL_OFFSETTOCARRIER_TAG; - cfg->num_tlv++; - - // InitialBWP configuration - - cfg->initialBWP_config.dl_bandwidth.value = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275); - cfg->initialBWP_config.dl_bandwidth.tl.tag = NFAPI_INITIALBWP_DL_BANDWIDTH_TAG; //temporary - cfg->num_tlv++; - cfg->initialBWP_config.dl_offset.value = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275); - cfg->initialBWP_config.dl_offset.tl.tag = NFAPI_INITIALBWP_DL_OFFSET_TAG; //temporary - cfg->num_tlv++; - cfg->initialBWP_config.dl_subcarrierSpacing.value = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; - cfg->initialBWP_config.dl_subcarrierSpacing.tl.tag = NFAPI_INITIALBWP_DL_SUBCARRIERSPACING_TAG; //temporary - cfg->num_tlv++; - LOG_I(PHY,"%s() initialBWP_dl_Bandwidth.RBstart.SCS :%d.%d.%d\n", __FUNCTION__, cfg->initialBWP_config.dl_bandwidth.value,cfg->initialBWP_config.dl_offset.value,cfg->initialBWP_config.dl_subcarrierSpacing.value); - - cfg->initialBWP_config.ul_bandwidth.value = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); - cfg->initialBWP_config.ul_bandwidth.tl.tag = NFAPI_INITIALBWP_UL_BANDWIDTH_TAG; - cfg->num_tlv++; - cfg->initialBWP_config.ul_offset.value = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); - cfg->initialBWP_config.ul_offset.tl.tag = NFAPI_INITIALBWP_UL_OFFSET_TAG; //temporary - cfg->num_tlv++; - cfg->initialBWP_config.ul_subcarrierSpacing.value = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; - cfg->initialBWP_config.ul_subcarrierSpacing.tl.tag = NFAPI_INITIALBWP_DL_SUBCARRIERSPACING_TAG; //temporary - cfg->num_tlv++; - LOG_I(PHY,"%s() initialBWP_ul_Bandwidth.RBstart.SCS :%d.%d.%d\n", __FUNCTION__, cfg->initialBWP_config.ul_bandwidth.value,cfg->initialBWP_config.ul_offset.value,cfg->initialBWP_config.ul_subcarrierSpacing.value); + for (i=0; i<5; i++) { + if (i==scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) { + cfg->carrier_config.ul_grid_size[i].value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + cfg->carrier_config.ul_k0[i].value = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; + cfg->carrier_config.ul_grid_size[i].tl.tag = NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG; + cfg->carrier_config.ul_k0[i].tl.tag = NFAPI_NR_CONFIG_UL_K0_TAG; + cfg->num_tlv++; + cfg->num_tlv++; + } + else { + cfg->carrier_config.ul_grid_size[i].value = 0; + cfg->carrier_config.ul_k0[i].value = 0; + } + } - cfg->rach_config.prach_RootSequenceIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; + // Cell configuration + cfg->cell_config.phy_cell_id.value = *scc->physCellId; + cfg->cell_config.phy_cell_id.tl.tag = NFAPI_NR_CONFIG_PHY_CELL_ID_TAG; + cfg->num_tlv++; + + cfg->cell_config.frame_duplex_type.value = 1; + cfg->cell_config.frame_duplex_type.tl.tag = NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG; + cfg->num_tlv++; + + + // SSB configuration + cfg->ssb_config.ss_pbch_power.value = scc->ss_PBCH_BlockPower; + cfg->ssb_config.ss_pbch_power.tl.tag = NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG; + cfg->num_tlv++; + + cfg->ssb_config.scs_common.value = *scc->ssbSubcarrierSpacing; + cfg->ssb_config.scs_common.tl.tag = NFAPI_NR_CONFIG_SCS_COMMON_TAG; + cfg->num_tlv++; + + // PRACH configuration + + cfg->prach_config.prach_sequence_length.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present; + cfg->prach_config.prach_sequence_length.tl.tag = NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG; + cfg->num_tlv++; + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) - cfg->rach_config.prach_msg1_SubcarrierSpacing.value = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; - else cfg->rach_config.prach_msg1_SubcarrierSpacing.value=cfg->rf_config.dl_subcarrierspacing.value; + cfg->prach_config.prach_sub_c_spacing.value = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + else + cfg->prach_config.prach_sub_c_spacing.value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + cfg->prach_config.prach_sub_c_spacing.tl.tag = NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG; + cfg->num_tlv++; - cfg->rach_config.restrictedSetConfig.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig; - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder) - cfg->rach_config.msg3_transformPrecoding.value = 1; - else cfg->rach_config.msg3_transformPrecoding.value = 0; + cfg->prach_config.restricted_set_config.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig; + cfg->prach_config.restricted_set_config.tl.tag = NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG; + cfg->num_tlv++; - cfg->rach_config.prach_ConfigurationIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; - cfg->rach_config.prach_msg1_FDM.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM; - cfg->rach_config.prach_msg1_FrequencyStart.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart; - cfg->rach_config.zeroCorrelationZoneConfig.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; - cfg->rach_config.preambleReceivedTargetPower.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower; + switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) { + case 0 : + cfg->prach_config.num_prach_fd_occasions.value = 1; + break; + case 1 : + cfg->prach_config.num_prach_fd_occasions.value = 2; + break; + case 2 : + cfg->prach_config.num_prach_fd_occasions.value = 4; + break; + case 3 : + cfg->prach_config.num_prach_fd_occasions.value = 8; + break; + default: + AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM); + } + cfg->prach_config.num_prach_fd_occasions.tl.tag = NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG; + cfg->num_tlv++; + cfg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions.value*sizeof(nfapi_nr_num_prach_fd_occasions_t)); + for (i=0; iprach_config.num_prach_fd_occasions.value; i++) { + cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i; + if (cfg->prach_config.prach_sequence_length.value) + cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; + else + cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839; + cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.tl.tag = NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG; + cfg->num_tlv++; + cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart; + cfg->prach_config.num_prach_fd_occasions_list[i].k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG; + cfg->num_tlv++; + cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; + cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.tl.tag = NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG; + cfg->num_tlv++; + //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = ??? + } + + cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + cfg->prach_config.ssb_per_rach.tl.tag = NFAPI_NR_CONFIG_SSB_PER_RACH_TAG; + cfg->num_tlv++; + + // SSB Table Configuration + int scs_scaling = 1<<(cfg->ssb_config.scs_common.value); + if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000) + scs_scaling = scs_scaling*3; + if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) + scs_scaling = scs_scaling>>2; + uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); + cfg->ssb_table.ssb_offset_point_a.value = absolute_diff/(12*scs_scaling); + cfg->ssb_table.ssb_offset_point_a.tl.tag = NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG; + cfg->num_tlv++; + cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell; + cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG; + cfg->num_tlv++; + + switch (scc->ssb_PositionsInBurst->present) { + case 1 : + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]; + cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; + break; + case 2 : + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]; + cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; + break; + case 3 : + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = 0; + cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; + for (i=0; i<4; i++) { + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<ssb_PositionsInBurst->present); + } + cfg->ssb_table.ssb_mask_list[0].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG; + cfg->num_tlv++; + + cfg->carrier_config.num_tx_ant.value = pdsch_AntennaPorts; + AssertFatal(pdsch_AntennaPorts > 0 && pdsch_AntennaPorts < 13, "pdsch_AntennaPorts in 1...12\n"); + cfg->carrier_config.num_tx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_TX_ANT_TAG; + int num_ssb=0; + for (int i=0;i<32;i++) { + num_ssb += (cfg->ssb_table.ssb_mask_list[0].ssb_mask.value>>i)&1; + num_ssb += (cfg->ssb_table.ssb_mask_list[1].ssb_mask.value>>i)&1; + } + + cfg->carrier_config.num_rx_ant.value = cfg->carrier_config.num_tx_ant.value; + cfg->carrier_config.num_rx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_RX_ANT_TAG; + LOG_I(MAC,"Set TX/RX antenna number to %d (num ssb %d: %x,%x)\n",cfg->carrier_config.num_tx_ant.value,num_ssb,cfg->ssb_table.ssb_mask_list[0].ssb_mask.value,cfg->ssb_table.ssb_mask_list[1].ssb_mask.value); + AssertFatal(cfg->carrier_config.num_tx_ant.value > 0,"carrier_config.num_tx_ant.value %d !\n",cfg->carrier_config.num_tx_ant.value ); + cfg->num_tlv++; + cfg->num_tlv++; + // TDD Table Configuration + //cfg->tdd_table.tdd_period.value = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity; + cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG; + cfg->num_tlv++; + if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL) + cfg->tdd_table.tdd_period.value = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity; + else { + AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL, + "scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n"); + cfg->tdd_table.tdd_period.value = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; + } + LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value); + if(cfg->cell_config.frame_duplex_type.value == TDD){ + int return_tdd = set_tdd_config_nr(cfg, + scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots, + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols + ); + + if (return_tdd !=0){ + LOG_E(PHY,"TDD configuration can not be done\n"); + } + else LOG_I(PHY,"TDD has been properly configurated\n"); + } + + +/* // PDCCH-ConfigCommon cfg->pdcch_config.controlResourceSetZero.value = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero; cfg->pdcch_config.searchSpaceZero.value = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero; @@ -188,19 +468,15 @@ void config_common(int Mod_idP, AssertFatal(cfg->pusch_config.num_PUSCHTimeDomainResourceAllocations.value<=NFAPI_NR_PUSCH_CONFIG_MAXALLOCATIONS,"illegal TimeDomainAllocation count %d\n",cfg->pusch_config.num_PUSCHTimeDomainResourceAllocations.value); for (int i=0;ipusch_config.num_PUSCHTimeDomainResourceAllocations.value;i++) { cfg->pusch_config.PUSCHTimeDomainResourceAllocation_k2[i].value=*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2; - } + }*/ - //cfg->sch_config.half_frame_index.value = 0; Fix in PHY - //cfg->sch_config.n_ssb_crb.value = 86; Fix in PHY } -/*void config_servingcellconfigcommon(){ - -}*/ int rrc_mac_config_req_gNB(module_id_t Mod_idP, int ssb_SubcarrierOffset, + int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc, int add_ue, uint32_t rnti, @@ -212,7 +488,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n"); - config_common(Mod_idP, + config_common(Mod_idP, + pdsch_AntennaPorts, scc); LOG_E(MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req); @@ -230,7 +507,11 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, phycfg.Mod_id = Mod_idP; phycfg.CC_id = 0; phycfg.cfg = &RC.nrmac[Mod_idP]->config[0]; - + + phycfg.cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset; + phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; + phycfg.cfg->num_tlv++; + if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg); } @@ -248,9 +529,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup; LOG_I(PHY,"Modified UE_id %d/%x with secondaryCellGroup\n",UE_id,rnti); } - fill_nfapi_coresets_and_searchspaces(secondaryCellGroup, - UE_list->coreset[UE_id], - UE_list->search_space[UE_id]); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 8ac85c64dd..73f51ed39a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -70,46 +70,50 @@ extern uint8_t nfapi_mode; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; -void clear_nr_nfapi_information(gNB_MAC_INST * gNB, +void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, - frame_t frameP, + frame_t frameP, sub_frame_t slotP){ - nfapi_nr_dl_config_request_t *DL_req = &gNB->DL_req[0]; - nfapi_ul_config_request_t *UL_req = &gNB->UL_req[0]; - nfapi_hi_dci0_request_t * HI_DCI0_req = &gNB->HI_DCI0_req[0]; - nfapi_tx_request_t *TX_req = &gNB->TX_req[0]; + nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0]; + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req[0]; + nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0]; + nfapi_nr_tx_data_request_t *TX_req = &gNB->TX_req[0]; gNB->pdu_index[CC_idP] = 0; if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF - DL_req[CC_idP].dl_config_request_body.number_dci = 0; - DL_req[CC_idP].dl_config_request_body.number_pdu = 0; - DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; - //DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; + DL_req[CC_idP].SFN = frameP; + DL_req[CC_idP].Slot = slotP; + DL_req[CC_idP].dl_tti_request_body.nPDUs = 0; + DL_req[CC_idP].dl_tti_request_body.nGroup = 0; + //DL_req[CC_idP].dl_tti_request_body.transmission_power_pcfich = 6000; - HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf = slotP + (frameP<<7); - HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci = 0; + UL_dci_req[CC_idP].SFN = frameP; + UL_dci_req[CC_idP].Slot = slotP; + UL_dci_req[CC_idP].numPdus = 0; + UL_tti_req[CC_idP].SFN = frameP; + UL_tti_req[CC_idP].Slot = slotP; + UL_tti_req[CC_idP].n_pdus = 0; + UL_tti_req[CC_idP].n_ulsch = 0; + UL_tti_req[CC_idP].n_ulcch = 0; + UL_tti_req[CC_idP].n_group = 0; - UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; - UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now - UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now - - TX_req[CC_idP].tx_request_body.number_of_pdus = 0; + TX_req[CC_idP].Number_of_PDUs = 0; } } /* -void check_nr_ul_failure(module_id_t module_idP, - int CC_id, +void check_nr_ul_failure(module_id_t module_idP, + int CC_id, int UE_id, - frame_t frameP, + frame_t frameP, sub_frame_t slotP) { UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list; - nfapi_nr_dl_config_request_t *DL_req = &RC.nrmac[module_idP]->DL_req[0]; + 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; @@ -122,11 +126,11 @@ void check_nr_ul_failure(module_id_t module_idP, UE_list->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_config_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu]; - memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); + 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]; + memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_dci_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + 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]. @@ -139,9 +143,9 @@ void check_nr_ul_failure(module_id_t module_idP, "illegal dl_Bandwidth %d\n", (int) cc[CC_id].mib->message.dl_Bandwidth); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = nr_pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; - DL_req[CC_id].dl_config_request_body.number_dci++; - DL_req[CC_id].dl_config_request_body.number_pdu++; - DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + DL_req[CC_id].dl_tti_request_body.number_dci++; + DL_req[CC_id].dl_tti_request_body.number_pdu++; + DL_req[CC_id].dl_tti_request_body.tl.tag = NFAPI_DL_TTI_REQUEST_BODY_TAG; LOG_I(MAC, "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", UE_id, rnti, @@ -191,13 +195,13 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram uint8_t TSFC; uint16_t deltaTSFC; // bitmap uint8_t srs_SubframeConfig; - + // table for TSFC (Period) and deltaSFC (offset) const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD - + uint16_t srsPeriodicity, srsOffset; - + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon; // check if SRS is enabled in this frame/subframe @@ -212,7 +216,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram } // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC uint16_t tmp = (subframeP % TSFC); - + if ((1 << tmp) & deltaTSFC) { // This is an SRS subframe, loop over UEs for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) { @@ -220,11 +224,11 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram 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, "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->present == SoundingRS_UL_ConfigDedicated_PR_setup) { get_srs_pos(&cc[CC_id], @@ -256,7 +260,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) } // for (UE_id ... } // if((1<UL_req_tmp[CC_id][slotP]; - nfapi_ul_config_request_t *ul_req = &mac->UL_req[CC_id]; - nfapi_ul_config_request_pdu_t *ul_req_pdu = ul_req->ul_config_request_body.ul_config_pdu_list; + nfapi_ul_config_request_t *ul_req = &mac->UL_tti_req[CC_id]; *ul_req = *ul_req_tmp; @@ -303,25 +306,35 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); } } +*/ -void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP){ +void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, + frame_t frame_rxP, + sub_frame_t slot_rxP, + frame_t frame_txP, + sub_frame_t slot_txP){ + protocol_ctxt_t ctxt; - int CC_id, i = -1; - NR_UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list; - rnti_t rnti; + int CC_id; + + NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels; + //nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL; start_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); - RC.nrmac[module_idP]->frame = frameP; - RC.nrmac[module_idP]->slot = slotP; + + // Check if there are downlink symbols in the slot, if not return, no scheduling opportunities + if (is_nr_DL_slot(cc->ServingCellConfigCommon,slot_txP)==0) return; + + RC.nrmac[module_idP]->frame = frame_rxP; + RC.nrmac[module_idP]->slot = slot_rxP; + memset(RC.nrmac[module_idP]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int)); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { //mbsfn_status[CC_id] = 0; @@ -329,7 +342,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, memset(cc[CC_id].vrb_map, 0, 100); memset(cc[CC_id].vrb_map_UL, 0, 100); - clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frameP, slotP); + clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP); } // refresh UE list based on UEs dropped by PHY in previous subframe @@ -339,13 +352,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; - if (nr_is_dci_opportunity(UE_list->search_space[i][1], - UE_list->coreset[i][1], - frameP, - slotP, - *cfg)) - nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP); - rnti = 0;//UE_RNTI(module_idP, i); CC_id = 0;//UE_PCCID(module_idP, i); @@ -353,32 +359,36 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } //END if (UE_list->active[i]) } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) */ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frameP, slotP,module_idP); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frame_txP, slot_txP,module_idP); - // pdcp_run(&ctxt); - + pdcp_run(&ctxt); //rrc_rx_tx(&ctxt, CC_id); // This schedules MIB - if((slotP == 0) && (frameP & 7) == 0){ - schedule_nr_mib(module_idP, frameP, slotP); + if((slot_txP == 0) && (frame_txP & 7) == 0){ + schedule_nr_mib(module_idP, frame_txP, slot_txP); } // Phytest scheduling/ option not activated because of pending bug + // Phytest scheduling - /*if (slotP==2) - nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);*/ - if (slotP==1) - nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP); + if (slot_rxP==2){ + nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP); + } + + if (slot_txP==1){ + nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL); + } + /* // 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_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 8dbdbc93fa..2983c699c0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -62,23 +62,20 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc; - nfapi_nr_dl_config_request_t *dl_config_request; - nfapi_nr_dl_config_request_body_t *dl_req; - nfapi_nr_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; + nfapi_nr_dl_tti_request_t *dl_tti_request; + nfapi_nr_dl_tti_request_body_t *dl_req; + nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu; int mib_sdu_length; int CC_id; - uint16_t sfn_sf = frameP << 7 | slotP; - AssertFatal(slotP == 0, "Subframe must be 0\n"); AssertFatal((frameP & 7) == 0, "Frame must be a multiple of 8\n"); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - dl_config_request = &gNB->DL_req[CC_id]; - dl_req = &dl_config_request->dl_config_request_body; + dl_tti_request = &gNB->DL_req[CC_id]; + dl_req = &dl_tti_request->dl_tti_request_body; cc = &gNB->common_channels[CC_id]; mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); // not used in this case @@ -87,38 +84,61 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ if (mib_sdu_length > 0) { - LOG_D(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->number_pdu, mib_sdu_length); + LOG_I(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_D(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length); + LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length); } - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE; - dl_config_pdu->pdu_size =2 + sizeof(nfapi_nr_dl_config_bch_pdu_rel15_t); - dl_config_pdu->bch_pdu_rel15.tl.tag = NFAPI_NR_DL_CONFIG_REQUEST_BCH_PDU_REL15_TAG; - dl_config_pdu->bch_pdu_rel15.length = mib_sdu_length; - dl_config_pdu->bch_pdu_rel15.pdu_index = gNB->pdu_index[CC_id]; - dl_config_pdu->bch_pdu_rel15.transmission_power = 6000; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - dl_req->number_pdu++; - dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_request->sfn_sf = sfn_sf; + dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE; + dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t); - LOG_D(MAC, "gNB->DL_req[0].number_pdu %d (%p)\n", dl_req->number_pdu, &dl_req->number_pdu); - // DL request - - TX_req = &gNB->TX_req[CC_id].tx_request_body.tx_pdu_list[gNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = 3; - TX_req->pdu_index = gNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 3; - TX_req->segments[0].segment_data = cc[CC_id].MIB_pdu.payload; - gNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - gNB->TX_req[CC_id].sfn_sf = sfn_sf; - gNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - gNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n"); + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *cc->ServingCellConfigCommon->physCellId; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0; + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count); + AssertFatal(cc->ServingCellConfigCommon->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n"); + AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n"); + long band = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + uint32_t ssb_offset0 = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + int ratio; + switch (*cc->ServingCellConfigCommon->ssbSubcarrierSpacing) { + case NR_SubcarrierSpacing_kHz15: + AssertFatal(band <= 79, "Band %ld is not possible for SSB with 15 kHz SCS\n",band); + if (band<77) // below 3GHz + ratio=3; // NRARFCN step is 5 kHz + else + ratio=1; // NRARFCN step is 15 kHz + break; + case NR_SubcarrierSpacing_kHz30: + AssertFatal(band <= 79, "Band %ld is not possible for SSB with 15 kHz SCS\n",band); + if (band<77) // below 3GHz + ratio=6; // NRARFCN step is 5 kHz + else + ratio=2; // NRARFCN step is 15 kHz + break; + case NR_SubcarrierSpacing_kHz120: + AssertFatal(band >= 257, "Band %ld is not possible for SSB with 120 kHz SCS\n",band); + ratio=2; // NRARFCN step is 15 kHz + break; + case NR_SubcarrierSpacing_kHz240: + AssertFatal(band >= 257, "Band %ld is not possible for SSB with 240 kHz SCS\n",band); + ratio=4; // NRARFCN step is 15 kHz + break; + default: + AssertFatal(1==0,"SCS %ld not allowed for SSB \n", *cc->ServingCellConfigCommon->ssbSubcarrierSpacing); + } + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = 0; //kSSB + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12); + 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++; } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index a17f73e2c8..89ba5f250c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -33,83 +33,151 @@ #include "mac_proto.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" -extern RAN_CONTEXT_t RC; +#include "executables/nr-softmodem.h" +#include "common/utils/nr/nr_common.h" -/*Scheduling of DLSCH with associated DCI in common search space +#include "NR_SCS-SpecificCarrier.h" +#include "NR_TDD-UL-DL-ConfigCommon.h" +#include "NR_FrequencyInfoUL.h" +#include "NR_RACH-ConfigGeneric.h" +#include "NR_RACH-ConfigCommon.h" +#include "NR_PUSCH-TimeDomainResourceAllocation.h" +#include "NR_PUSCH-ConfigCommon.h" +#include "NR_PUCCH-ConfigCommon.h" +#include "NR_PDSCH-TimeDomainResourceAllocation.h" +#include "NR_PDSCH-ConfigCommon.h" +#include "NR_RateMatchPattern.h" +#include "NR_RateMatchPatternLTE-CRS.h" +#include "NR_SearchSpace.h" +#include "NR_ControlResourceSet.h" + +extern RAN_CONTEXT_t RC; +//#define ENABLE_MAC_PAYLOAD_DEBUG 1 + +/*Scheduling of DLSCH with associated DCI in common search space on initialBWP * current version has only a DCI for type 1 PDCCH for C_RNTI*/ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP) -{ + sub_frame_t slotP) { uint8_t CC_id; + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; + nfapi_nr_dl_tti_request_body_t *dl_req; + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu; + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu; + nfapi_nr_pdu_t *TX_req; - gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = nr_mac->common_channels; - nfapi_nr_dl_config_request_body_t *dl_req; - nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; - nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; - nfapi_tx_request_pdu_t *TX_req; - - nfapi_nr_config_request_t *cfg = &nr_mac->config[0]; uint16_t rnti = 0x1234; + + // int time_domain_assignment,k0; - uint16_t sfn_sf = frameP << 7 | slotP; - int dlBWP_carrier_bandwidth = cfg->initialBWP_config.dl_bandwidth.value; + NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon; - // everything here is hard-coded to 30 kHz - int scs = get_dlscs(cfg); - int slots_per_frame = get_spf(cfg); + int dlBWP_carrier_bandwidth = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275); + + + /* + int scs = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; + + int slots_per_frame = 10*(1<downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1; + */ for (CC_id=0; CC_idinitialBWP_config.dl_bandwidth.value,cfg->initialBWP_config.dl_offset.value); + LOG_D(MAC, "Scheduling common search space DCI type 1 dlBWP BW.firstRB %d.%d\n", + dlBWP_carrier_bandwidth, + NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275)); + + + dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + 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)); + + 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 = rnti; + pdsch_pdu_rel15->pduIndex = 0; - dl_req = &nr_mac->DL_req[CC_id].dl_config_request_body; - dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); - dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu)); + // BWP + pdsch_pdu_rel15->BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275); + pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275); + pdsch_pdu_rel15->SubcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; + pdsch_pdu_rel15->CyclicPrefix = 0; + pdsch_pdu_rel15->NrOfCodewords = 1; + int mcsIndex = 9; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0); + pdsch_pdu_rel15->qamModOrder[0] = 2; + pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; + pdsch_pdu_rel15->mcsTable[0] = 0; + pdsch_pdu_rel15->rvIndex[0] = 0; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; // Point A + + pdsch_pdu_rel15->dmrsConfigType = 0; // Type 1 by default for InitialBWP + pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu_rel15->SCID = 0; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = 0; + pdsch_pdu_rel15->rbSize = 6; + pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP + // choose shortest PDSCH + int startSymbolAndLength=0; + int StartSymbolIndex=-1,NrOfSymbols=14; + int StartSymbolIndex_tmp,NrOfSymbols_tmp; - dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1]; - memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); - dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu)); + for (int i=0; + idownlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; + i++) { + startSymbolAndLength = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength,&StartSymbolIndex_tmp,&NrOfSymbols_tmp); + if (NrOfSymbols_tmp < NrOfSymbols) { + NrOfSymbols = NrOfSymbols_tmp; + StartSymbolIndex = StartSymbolIndex_tmp; + // k0 = *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0; + // time_domain_assignment = i; + } + } + AssertFatal(StartSymbolIndex>=0,"StartSymbolIndex is negative\n"); + pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, + scc->dmrs_TypeA_Position, + NrOfSymbols); - nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15; - - dlsch_pdu_rel15->start_prb = 0; - dlsch_pdu_rel15->n_prb = 6; - - dlsch_pdu_rel15->rnti = rnti; - dlsch_pdu_rel15->nb_layers =1; - dlsch_pdu_rel15->nb_codewords = 1; - dlsch_pdu_rel15->mcs_idx = 9; - dlsch_pdu_rel15->ndi = 1; - dlsch_pdu_rel15->redundancy_version = 0; - - dlsch_pdu_rel15->dmrs_TypeA_Position = cfg->pdsch_config.dmrs_TypeA_Position.value; - - nr_configure_css_dci_initial(params_rel15, + /* + AssertFatal(k0==0,"k0 is not zero for Initial DL BWP TimeDomain Alloc\n"); + nr_configure_css_dci_initial(pdcch_pdu_rel15, scs, scs, - nr_FR1, + FR, 0, 0, 0, sfn_sf, slotP, slots_per_frame, dlBWP_carrier_bandwidth); - - params_rel15->first_slot = 0; - - pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value); - pdu_rel15->time_domain_assignment = 0; - - - dlsch_pdu_rel15->start_symbol = extract_startSymbol(cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_startSymbolAndLength[pdu_rel15->time_domain_assignment].value); - dlsch_pdu_rel15->nb_symbols = extract_length(cfg->pdsch_config.PDSCHTimeDomainResourceAllocation_startSymbolAndLength[pdu_rel15->time_domain_assignment].value); + + + pdu_rel15->frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->rbStart, + dlBWP_carrier_bandwidth); + pdu_rel15->time_domain_assignment = time_domain_assignment; + pdu_rel15->vrb_to_prb_mapping = 1; pdu_rel15->mcs = 9; pdu_rel15->tb_scaling = 1; @@ -123,16 +191,16 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, pdu_rel15->tpc = 2; pdu_rel15->pucch_resource_indicator = 7; pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; - + LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", - pdu_rel15->frequency_domain_assignment, - pdu_rel15->time_domain_assignment, - pdu_rel15->vrb_to_prb_mapping, - pdu_rel15->mcs, - pdu_rel15->tb_scaling, - pdu_rel15->ndi, - pdu_rel15->rv); - + pdu_rel15->frequency_domain_assignment, + pdu_rel15->time_domain_assignment, + pdu_rel15->vrb_to_prb_mapping, + pdu_rel15->mcs, + pdu_rel15->tb_scaling, + pdu_rel15->ndi, + pdu_rel15->rv); + params_rel15->rnti = rnti; params_rel15->rnti_type = NFAPI_NR_RNTI_C; params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0; @@ -140,184 +208,651 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, LOG_D(MAC, "DCI type 1 params: rnti %x, rnti_type %d, dci_format %d\n \ coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \ ss params : nb_ss_sets_per_slot %d, first symb %d, nb_slots %d, sfn_mod2 %d, first slot %d\n", - params_rel15->rnti, - params_rel15->rnti_type, - params_rel15->dci_format, - params_rel15->mux_pattern, - params_rel15->n_rb, - params_rel15->n_symb, - params_rel15->rb_offset, - params_rel15->nb_ss_sets_per_slot, - params_rel15->first_symbol, - params_rel15->nb_slots, - params_rel15->sfn_mod2, - params_rel15->first_slot); - nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu); - 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\n", - dlsch_pdu_rel15->start_prb, - dlsch_pdu_rel15->n_prb, - dlsch_pdu_rel15->start_symbol, - dlsch_pdu_rel15->nb_symbols, - dlsch_pdu_rel15->nb_layers, - dlsch_pdu_rel15->nb_codewords, - dlsch_pdu_rel15->mcs_idx); + params_rel15->rnti, + params_rel15->rnti_type, + params_rel15->dci_format, + params_rel15->mux_pattern, + params_rel15->n_rb, + params_rel15->n_symb, + params_rel15->rb_offset, + params_rel15->nb_ss_sets_per_slot, + params_rel15->first_symbol, + params_rel15->nb_slots, + params_rel15->sfn_mod2, + params_rel15->first_slot); + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, dl_tti_dci_pdu->dci_dl_pdu,0); + 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\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]); + */ + + dl_req->nPDUs+=2; + + TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + TX_req->PDU_length = 6; + TX_req->PDU_index = nr_mac->pdu_index[CC_id]++; + TX_req->num_TLV = 1; + TX_req->TLVs[0].length = 8; + memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length); + nr_mac->TX_req[CC_id].Number_of_PDUs++; + nr_mac->TX_req[CC_id].SFN=frameP; + nr_mac->TX_req[CC_id].Slot=slotP; + } +} - dl_req->number_dci++; - dl_req->number_pdsch_rnti++; - dl_req->number_pdu+=2; +int configure_fapi_dl_Tx(int Mod_idP, + int *CCEIndex, + nfapi_nr_dl_tti_request_body_t *dl_req, + nfapi_nr_pdu_t *TX_req, + uint8_t *mcsIndex, + uint16_t *rbSize, + uint16_t *rbStart) { - TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = 6; - TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 8; - TX_req->segments[0].segment_data = &cc[CC_id].RAR_pdu.payload[0]; - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + + gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; + NR_COMMON_channels_t *cc = nr_mac->common_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu; + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu; + int TBS; + + + int bwp_id=1; + + int UE_id = 0; + NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + + + 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[bwp_id-1]; + + + 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)); + + 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_list->rnti[UE_id]; + pdsch_pdu_rel15->pduIndex = 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; + int mcs = (mcsIndex!=NULL) ? *mcsIndex : 9; + 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] = 0; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; // Point A + + 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; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 1; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = (rbStart!=NULL) ? *rbStart : 0; + pdsch_pdu_rel15->rbSize = (rbSize!=NULL) ? *rbSize : pdsch_pdu_rel15->BWPSize; + pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP + // choose shortest PDSCH + int startSymbolAndLength=0; + int time_domain_assignment=2; + int StartSymbolIndex,NrOfSymbols; + + AssertFatal(time_domain_assignmentbwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count,"time_domain_assignment %d>=%d\n",time_domain_assignment,bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count); + startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols); + 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]; + + dci_pdu_rel15[0].frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->rbStart, + NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275)); + dci_pdu_rel15[0].time_domain_assignment = time_domain_assignment; // row index used here instead of SLIV; + dci_pdu_rel15[0].vrb_to_prb_mapping = 1; + dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0]; + dci_pdu_rel15[0].tb_scaling = 1; + + dci_pdu_rel15[0].ra_preamble_index = 25; + dci_pdu_rel15[0].format_indicator = 1; + dci_pdu_rel15[0].ndi = 1; + dci_pdu_rel15[0].rv = 0; + dci_pdu_rel15[0].harq_pid = 0; + dci_pdu_rel15[0].dai = 2; + dci_pdu_rel15[0].tpc = 2; + dci_pdu_rel15[0].pucch_resource_indicator = 7; + dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator = 7; + + 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, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), + dci_pdu_rel15[0].time_domain_assignment, + dci_pdu_rel15[0].vrb_to_prb_mapping, + dci_pdu_rel15[0].mcs, + dci_pdu_rel15[0].tb_scaling, + dci_pdu_rel15[0].ndi, + dci_pdu_rel15[0].rv); - } + nr_configure_pdcch(pdcch_pdu_rel15, + 1, // ue-specific + scc, + bwp); + + + + + pdcch_pdu_rel15->numDlDci = 1; + pdcch_pdu_rel15->AggregationLevel[0] = 4; + pdcch_pdu_rel15->RNTI[0]=UE_list->rnti[0]; + pdcch_pdu_rel15->CceIndex[0] = CCEIndex[0]; + pdcch_pdu_rel15->beta_PDCCH_1_0[0]=0; + pdcch_pdu_rel15->powerControlOffsetSS[0]=1; + + int dci_formats[2]; + int rnti_types[2]; + + dci_formats[0] = NR_DL_DCI_FORMAT_1_0; + rnti_types[0] = NR_RNTI_C; + + pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize); + fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types); + + LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d\n \ + coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + pdcch_pdu_rel15->RNTI[0], + rnti_types[0], + dci_formats[0], + (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols); + + int x_Overhead = 0; // should be 0 for initialBWP + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, + x_Overhead); + // Hardcode it for now + TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]; + 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, + pdsch_pdu_rel15->rbSize, + startSymbolAndLength, + 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; + + + TX_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; + TX_req->PDU_index = nr_mac->pdu_index[0]++; + + // TX_req->num_TLV = 1; + // TX_req->TLVs[0].length = 8; + // memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length); + + return TBS; //Return TBS in bytes } -/*Scheduling of DLSCH with associated DCI in user specific search space - * current version has only a DCI for type 1 PDCCH for C_RNTI*/ +void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types) { + + dci_pdu_rel15->frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, + pusch_pdu->rb_start, + NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); + + dci_pdu_rel15->time_domain_assignment = 2; // row index used here instead of SLIV; + dci_pdu_rel15->frequency_hopping_flag = 0; + dci_pdu_rel15->mcs = 9; + + dci_pdu_rel15->format_indicator = 0; + dci_pdu_rel15->ndi = 1; + dci_pdu_rel15->rv = 0; + dci_pdu_rel15->harq_pid = 0; + dci_pdu_rel15->tpc = 2; + + LOG_D(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", + pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci], + dci_pdu_rel15->frequency_domain_assignment, + dci_pdu_rel15->time_domain_assignment, + dci_pdu_rel15->frequency_hopping_flag, + dci_pdu_rel15->mcs, + dci_pdu_rel15->tpc, + dci_pdu_rel15->ndi, + dci_pdu_rel15->rv); + + dci_formats[pdcch_pdu_rel15->numDlDci] = NR_UL_DCI_FORMAT_0_0; + rnti_types[pdcch_pdu_rel15->numDlDci] = NR_RNTI_C; + pdcch_pdu_rel15->numDlDci++; + +} + + + void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP) + sub_frame_t slotP, + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config) { - uint8_t CC_id; - + LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest \n"); + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; //NR_COMMON_channels_t *cc = nr_mac->common_channels; - nfapi_nr_dl_config_request_body_t *dl_req; - nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu; - nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu; - nfapi_tx_request_pdu_t *TX_req; + //NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon; + nfapi_nr_dl_tti_request_body_t *dl_req; + nfapi_nr_pdu_t *TX_req; - nfapi_nr_config_request_t *cfg = &nr_mac->config[0]; - uint16_t rnti = 0x1234; + int TBS; + int TBS_bytes; + int lcid; + int ta_len = 0; + int header_length_total=0; + int header_length_last; + int sdu_length_total = 0; + mac_rlc_status_resp_t rlc_status; + uint16_t sdu_lengths[NB_RB_MAX]; + int num_sdus = 0; + unsigned char dlsch_buffer[MAX_NR_DLSCH_PAYLOAD_BYTES]; + int offset; + int UE_id = 0; + unsigned char sdu_lcids[NB_RB_MAX]; + int padding = 0, post_padding = 0; + NR_UE_list_t *UE_list = &nr_mac->UE_list; + uint16_t rnti = UE_list->rnti[UE_id]; + DLSCH_PDU dlsch_pdu; + //PDSCH_PDU *pdsch_pdu = (PDSCH_PDU*) malloc(sizeof(PDSCH_PDU)); + + if (UE_list->num_UEs ==0) return; + + int CCEIndex=-1; + + LOG_D(MAC, "Scheduling UE specific search space DCI type 1\n"); + int CC_id=0; + dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + + //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving + //through the LTE stack + if (IS_SOFTMODEM_NOS1){ + + memset(&dlsch_pdu, 0, sizeof(DLSCH_PDU)); + int ta_update = 31; + ta_len = 0; + + // Hardcode it for now + TBS = 6784/8; //TBS in bytes + //TBS = dl_tti_pdsch_pdu->pdsch_pdu.dlsch_pdu_rel15.transport_block_size; + + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + // TODO: check if the lcid is active + + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, frameP, lcid, TBS, + TBS - ta_len - header_length_total - sdu_length_total - 3); + + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + slotP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_length_total - sdu_length_total - 3 + //#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, 0 + //#endif + ); + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, + "[eNB %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_idP, frameP, + TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, + header_length_total, + TBS); - uint16_t sfn_sf = frameP << 7 | slotP; - int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value; + CCEIndex = allocate_nr_CCEs(nr_mac, + 1, // bwp_id + 0, // coreset_id + 4, // aggregation, + 1, // search_space, 0 common, 1 ue-specific + UE_id, + 0); // m + if (CCEIndex == -1) return; - // everything here is hard-coded to 30 kHz - //int scs = get_dlscs(cfg); - //int slots_per_frame = get_spf(cfg); - for (CC_id=0; CC_id= MAKE_VERSION(14, 0, 0)) + ,0, 0 + //#endif + ); + + + + LOG_D(MAC, + "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, 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++; + } + } else { + // no TBS left + break; + } + } + + // last header does not have length field + if (header_length_total) { + header_length_total -= header_length_last; + header_length_total++; + } + + + if (ta_len + sdu_length_total + header_length_total > 0) { + + + if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { + padding = TBS - header_length_total - sdu_length_total - ta_len; + post_padding = 0; + } else { + padding = 0; + post_padding = 1; + } + + offset = generate_dlsch_header((unsigned char *)nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], //DLSCH_pdu.payload[0], + num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, post_padding); - nfapi_nr_coreset_t* coreset = &nr_mac->UE_list.coreset[0][1]; - nfapi_nr_search_space_t* search_space = &nr_mac->UE_list.search_space[0][1]; + LOG_D(MAC, "Offset bits: %d \n", offset); + + // Probably there should be other actions done before that + // cycle through SDUs and place in dlsch_buffer + + //memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); + memcpy(&nr_mac->UE_list.DLSCH_pdu[0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); + + + // fill remainder of DLSCH with 0 + for (int j = 0; j < (TBS - sdu_length_total - offset); j++) { + //UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; + nr_mac->UE_list.DLSCH_pdu[0][0].payload[0][offset + sdu_length_total + j] = 0; + } - dl_req = &nr_mac->DL_req[CC_id].dl_config_request_body; - dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); - dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu)); + AssertFatal(CCEIndex>0,"CCEIndex is negative\n"); + int CCEIndices[2]; + CCEIndices[0] = CCEIndex; - dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1]; - memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t)); - dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu)); + TBS_bytes = configure_fapi_dl_Tx(module_idP, + CCEIndices, + dl_req, + TX_req, + dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, + dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, + dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, , TBS size: %d \n \n", frameP, slotP, TBS_bytes); + for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8 + LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); + } +#endif + + 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);; + + + nr_mac->TX_req[CC_id].Number_of_PDUs++; + nr_mac->TX_req[CC_id].SFN = frameP; + nr_mac->TX_req[CC_id].Slot = slotP; + } //if (ta_len + sdu_length_total + header_length_total > 0) + } //if (IS_SOFTMODEM_NOS1) + + //When the --NOS1 option is not enabled, DLSCH transmissions with random data + //occur every time that the current function is called (dlsch phytest mode) + else{ + CCEIndex = allocate_nr_CCEs(nr_mac, + 1, // bwp_id + 0, // coreset_id + 4, // aggregation, + 1, // search_space, 0 common, 1 ue-specific + UE_id, + 0); // m + AssertFatal(CCEIndex>=0,"CCEIndex is negative\n"); + if (CCEIndex == -1) return; - nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15; - nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15; - - dlsch_pdu_rel15->start_prb = 0; - dlsch_pdu_rel15->n_prb = 50; - dlsch_pdu_rel15->start_symbol = 2; - dlsch_pdu_rel15->nb_symbols = 9; - dlsch_pdu_rel15->rnti = rnti; - dlsch_pdu_rel15->nb_layers =1; - dlsch_pdu_rel15->nb_codewords = 1; - dlsch_pdu_rel15->mcs_idx = 9; - dlsch_pdu_rel15->ndi = 1; - dlsch_pdu_rel15->redundancy_version = 0; - - nr_configure_dci_from_pdcch_config(params_rel15, - coreset, - search_space, - *cfg, - dl_carrier_bandwidth); - - pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value); - pdu_rel15->time_domain_assignment = 3; // row index used here instead of SLIV; - pdu_rel15->vrb_to_prb_mapping = 1; - pdu_rel15->mcs = 9; - pdu_rel15->tb_scaling = 1; - - pdu_rel15->ra_preamble_index = 25; - pdu_rel15->format_indicator = 1; - pdu_rel15->ndi = 1; - pdu_rel15->rv = 0; - pdu_rel15->harq_pid = 0; - pdu_rel15->dai = 2; - pdu_rel15->tpc = 2; - pdu_rel15->pucch_resource_indicator = 7; - pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7; - - LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", - pdu_rel15->frequency_domain_assignment, - pdu_rel15->time_domain_assignment, - pdu_rel15->vrb_to_prb_mapping, - pdu_rel15->mcs, - pdu_rel15->tb_scaling, - pdu_rel15->ndi, - pdu_rel15->rv); - - params_rel15->rnti = rnti; - params_rel15->rnti_type = NFAPI_NR_RNTI_C; - params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0; - - //params_rel15->aggregation_level = 1; - LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \ - coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \ - ss params : first symb %d, ss type %d\n", - params_rel15->rnti, - params_rel15->rnti_type, - params_rel15->config_type, - params_rel15->dci_format, - params_rel15->mux_pattern, - params_rel15->n_rb, - params_rel15->n_symb, - params_rel15->rb_offset, - params_rel15->first_symbol, - params_rel15->search_space_type); - nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu); - 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\n", - dlsch_pdu_rel15->start_prb, - dlsch_pdu_rel15->n_prb, - dlsch_pdu_rel15->start_symbol, - dlsch_pdu_rel15->nb_symbols, - dlsch_pdu_rel15->nb_layers, - dlsch_pdu_rel15->nb_codewords, - dlsch_pdu_rel15->mcs_idx); - - dl_req->number_dci++; - dl_req->number_pdsch_rnti++; - dl_req->number_pdu+=2; - - TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size; - TX_req->pdu_index = nr_mac->pdu_index[CC_id]++; - TX_req->num_segments = 1; - - // HOT FIX for all zero pdu problem - // ------------------------------------------------------------------------------------------------ - for(int i = 0; i < dlsch_pdu_rel15->transport_block_size/8; i++) { - ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) rand(); - } - // ------------------------------------------------------------------------------------------------ - - TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[0][0].payload[0]; - TX_req->segments[0].segment_length = dlsch_pdu_rel15->transport_block_size+2; - nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - nr_mac->TX_req[CC_id].sfn_sf = sfn_sf; - nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST; + int CCEIndices[2]; + CCEIndices[0] = CCEIndex; + LOG_D(MAC,"Configuring DL_TX in %d.%d\n",frameP,slotP); + TBS_bytes = configure_fapi_dl_Tx(module_idP,CCEIndices,dl_req, TX_req, + dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, + dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, + dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); +// HOT FIX for all zero pdu problem +// ------------------------------------------------------------------------------------------------ + LOG_D(MAC,"Filling %d bytes in DL_TX\n",TBS_bytes); + for(int i = 0; i < TBS_bytes; i++) { // + ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff); + //LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); + } +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + 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 *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); + } + } +#endif + + //TX_req->segments[0].segment_length = 8; + 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); + + nr_mac->TX_req[CC_id].Number_of_PDUs++; + nr_mac->TX_req[CC_id].SFN = frameP; + nr_mac->TX_req[CC_id].Slot = slotP; + // ------------------------------------------------------------------------------------------------ } } + + +void nr_schedule_uss_ulsch_phytest(int Mod_idP, + frame_t frameP, + sub_frame_t slotP) { + + 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 bwp_id=1; + + 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_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[bwp_id-1]; + NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; + nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0]; + + + uint16_t rnti = UE_list->rnti[UE_id]; + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu; + + UL_tti_req->SFN = frameP; + UL_tti_req->Slot = slotP; + UL_tti_req->n_pdus = 1; + UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; + memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); + + LOG_D(MAC, "Scheduling UE specific PUSCH\n"); + //UL_tti_req = &nr_mac->UL_tti_req[CC_id]; + /* + // original configuration + rel15_ul->rnti = 0x1234; + rel15_ul->ulsch_pdu_rel15.start_rb = 30; + rel15_ul->ulsch_pdu_rel15.number_rbs = 50; + rel15_ul->ulsch_pdu_rel15.start_symbol = 2; + rel15_ul->ulsch_pdu_rel15.number_symbols = 12; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; + rel15_ul->ulsch_pdu_rel15.Qm = 2; + rel15_ul->ulsch_pdu_rel15.mcs = 9; + rel15_ul->ulsch_pdu_rel15.rv = 0; + rel15_ul->ulsch_pdu_rel15.n_layers = 1; + */ + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = rnti; + pusch_pdu->handle = 0; //not yet used + + pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + pusch_pdu->cyclic_prefix = 0; + //pusch information always include + //this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined. + pusch_pdu->mcs_index = 9; + pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = 0; //It equals the higher-layer parameter Data-scrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id.; + pusch_pdu->nrOfLayers = 1; + //DMRS + pusch_pdu->ul_dmrs_symb_pos = 1; + pusch_pdu->dmrs_config_type = 0; //dmrs-type 1 (the one with a single DMRS symbol in the beginning) + pusch_pdu->ul_dmrs_scrambling_id = 0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. + pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. + //pusch_pdu->num_dmrs_cdm_grps_no_data; + //pusch_pdu->dmrs_ports; //DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + pusch_pdu->resource_alloc = 1; //type 1 + //pusch_pdu->rb_bitmap;// for ressource alloc type 0 + pusch_pdu->rb_start = 0; + pusch_pdu->rb_size = 50; + pusch_pdu->vrb_to_prb_mapping = 0; + pusch_pdu->frequency_hopping = 0; + //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + //Resource Allocation in time domain + pusch_pdu->start_symbol_index = 2; + pusch_pdu->nr_of_symbols = 12; + //Optional Data only included if indicated in pduBitmap + pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI + 0, //nb_rb_oh + pusch_pdu->nrOfLayers = 1); + pusch_pdu->pusch_data.num_cb = 0; //CBG not supported + //pusch_pdu->pusch_data.cb_present_and_position; + //pusch_pdu->pusch_uci; + //pusch_pdu->pusch_ptrs; + //pusch_pdu->dfts_ofdm; + //beamforming + //pusch_pdu->beamforming; //not used for now + + + ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus]; + memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t)); + ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; + + int dci_formats[2]; + int rnti_types[2]; + + int CCEIndex = allocate_nr_CCEs(nr_mac, + 1, // bwp_id + 0, // coreset_id + 4, // aggregation, + 1, // search_space, 0 common, 1 ue-specific + UE_id, + 0); // m + + dci_formats[0] = NR_UL_DCI_FORMAT_0_0; + rnti_types[0] = NR_RNTI_C; + LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP); + nr_configure_pdcch(pdcch_pdu_rel15, + 1, // ue-specific, + scc, + bwp); + + + dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; + + AssertFatal(CCEIndex>=0,"CCEIndex is negative \n"); + pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci] = CCEIndex; + + LOG_D(PHY,"CCEIndex %d\n",pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci]); + + config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); + + pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize); + fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types); + +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 2aad88158b..df9c37f687 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -39,6 +39,7 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "common/utils/nr/nr_common.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" @@ -59,9 +60,12 @@ #include "NR_ControlResourceSet.h" #include "NR_SearchSpace.h" +#include "nfapi_nr_interface.h" + #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_gNB_SCHEDULER 1 + #include "common/ran_context.h" extern RAN_CONTEXT_t RC; @@ -127,12 +131,69 @@ static inline uint8_t get_max_cces(uint8_t scs) { return (nr_max_number_of_cces_per_slot[scs]); } -int is_nr_UL_slot(NR_COMMON_channels_t * ccP, int slot){ +int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, + int bwp_id, + int coreset_id, + int aggregation, + int search_space, // 0 common, 1 ue-specific + int UE_id, + int m + ) { + // 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; + + if (search_space == 1) { + AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id); + secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[coreset_id]; + } + else { + AssertFatal(1==0,"Add code for common search space\n"); + } + + int *cce_list = nr_mac->cce_list[bwp_id][coreset_id]; + + + int n_rb=0; + for (int i=0;i<6;i++) + for (int j=0;j<8;j++) { + n_rb+=((coreset->frequencyDomainResources.buf[i]>>j)&1); + } + 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}; + + 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 + } + int first_cce = aggregation * (( Y + (m*N_cce)/(aggregation*M_s_max) + n_CI ) % CEILIDIV(N_cce,aggregation)); + + for (int i=0;i>4)&0xf; - uint8_t mu = scs_common; - uint8_t O_scale=0, M_scale=0; // used to decide if the values of O and M need to be divided by 2 + // uint8_t O, M; + // uint8_t ss_idx = rmsi_pdcch_config&0xf; + // uint8_t cset_idx = (rmsi_pdcch_config>>4)&0xf; + // uint8_t mu = scs_common; + // uint8_t O_scale=0, M_scale=0; // used to decide if the values of O and M need to be divided by 2 + AssertFatal(1==0,"todo\n"); + /* /// Coreset params switch(scs_common) { @@ -158,18 +221,18 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p switch(pdcch_scs) { case kHz15: AssertFatal(cset_idx<15,"Coreset index %d reserved for scs kHz15/kHz15\n", cset_idx); - pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = (cset_idx < 6)? 24 : (cset_idx < 12)? 48 : 96; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_15_15[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_15_15[cset_idx]; + pdcch_pdu->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_pdu->n_rb = (cset_idx < 6)? 24 : (cset_idx < 12)? 48 : 96; + pdcch_pdu->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_15_15[cset_idx]; + pdcch_pdu->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_15_15[cset_idx]; break; case kHz30: AssertFatal(cset_idx<14,"Coreset index %d reserved for scs kHz15/kHz30\n", cset_idx); - pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = (cset_idx < 8)? 24 : 48; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_15_30[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_15_15[cset_idx]; + pdcch_pdu->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_pdu->n_rb = (cset_idx < 8)? 24 : 48; + pdcch_pdu->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_15_30[cset_idx]; + pdcch_pdu->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_15_15[cset_idx]; break; default: @@ -184,17 +247,17 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p switch(pdcch_scs) { case kHz15: AssertFatal(cset_idx<9,"Coreset index %d reserved for scs kHz30/kHz15\n", cset_idx); - pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = (cset_idx < 10)? 48 : 96; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_15_b40Mhz[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_15_b40Mhz[cset_idx]; + pdcch_pdu->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_pdu->n_rb = (cset_idx < 10)? 48 : 96; + pdcch_pdu->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_15_b40Mhz[cset_idx]; + pdcch_pdu->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_15_b40Mhz[cset_idx]; break; case kHz30: - pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = (cset_idx < 6)? 24 : 48; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_30_b40Mhz[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_30_b40Mhz[cset_idx]; + pdcch_pdu->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_pdu->n_rb = (cset_idx < 6)? 24 : 48; + pdcch_pdu->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_30_b40Mhz[cset_idx]; + pdcch_pdu->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_30_b40Mhz[cset_idx]; break; default: @@ -206,18 +269,18 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p switch(pdcch_scs) { case kHz15: AssertFatal(cset_idx<9,"Coreset index %d reserved for scs kHz30/kHz15\n", cset_idx); - pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = (cset_idx < 3)? 48 : 96; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_15_a40Mhz[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_15_a40Mhz[cset_idx]; + pdcch_pdu->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_pdu->n_rb = (cset_idx < 3)? 48 : 96; + pdcch_pdu->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_15_a40Mhz[cset_idx]; + pdcch_pdu->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_15_a40Mhz[cset_idx]; break; case kHz30: AssertFatal(cset_idx<10,"Coreset index %d reserved for scs kHz30/kHz30\n", cset_idx); - pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = (cset_idx < 4)? 24 : 48; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_30_a40Mhz[cset_idx]; - pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_30_a40Mhz[cset_idx]; + pdcch_pdu->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_pdu->n_rb = (cset_idx < 4)? 24 : 48; + pdcch_pdu->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_30_30_a40Mhz[cset_idx]; + pdcch_pdu->rb_offset = nr_coreset_rb_offset_pdcch_type_0_scs_30_30_a40Mhz[cset_idx]; break; default: @@ -230,19 +293,19 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p switch(pdcch_scs) { case kHz60: AssertFatal(cset_idx<12,"Coreset index %d reserved for scs kHz120/kHz60\n", cset_idx); - pdcch_params->mux_pattern = (cset_idx < 8)?NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2; - pdcch_params->n_rb = (cset_idx < 6)? 48 : (cset_idx < 8)? 96 : (cset_idx < 10)? 48 : 96; - pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_120_60[cset_idx]; - pdcch_params->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_120_60[cset_idx]>0)?nr_coreset_rb_offset_pdcch_type_0_scs_120_60[cset_idx] : + pdcch_pdu->mux_pattern = (cset_idx < 8)?NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2; + pdcch_pdu->n_rb = (cset_idx < 6)? 48 : (cset_idx < 8)? 96 : (cset_idx < 10)? 48 : 96; + pdcch_pdu->n_symb = nr_coreset_nsymb_pdcch_type_0_scs_120_60[cset_idx]; + pdcch_pdu->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_120_60[cset_idx]>0)?nr_coreset_rb_offset_pdcch_type_0_scs_120_60[cset_idx] : (k_ssb == 0)? -41 : -42; break; case kHz120: AssertFatal(cset_idx<8,"Coreset index %d reserved for scs kHz120/kHz120\n", cset_idx); - pdcch_params->mux_pattern = (cset_idx < 4)?NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3; - pdcch_params->n_rb = (cset_idx < 2)? 24 : (cset_idx < 4)? 48 : (cset_idx < 6)? 24 : 48; - pdcch_params->n_symb = (cset_idx == 2)? 1 : 2; - pdcch_params->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_120_120[cset_idx]>0)? nr_coreset_rb_offset_pdcch_type_0_scs_120_120[cset_idx] : + pdcch_pdu->mux_pattern = (cset_idx < 4)?NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3; + pdcch_pdu->n_rb = (cset_idx < 2)? 24 : (cset_idx < 4)? 48 : (cset_idx < 6)? 24 : 48; + pdcch_pdu->n_symb = (cset_idx == 2)? 1 : 2; + pdcch_pdu->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_120_120[cset_idx]>0)? nr_coreset_rb_offset_pdcch_type_0_scs_120_120[cset_idx] : (k_ssb == 0)? -20 : -21; break; @@ -255,18 +318,18 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p switch(pdcch_scs) { case kHz60: AssertFatal(cset_idx<4,"Coreset index %d reserved for scs kHz240/kHz60\n", cset_idx); - pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; - pdcch_params->n_rb = 96; - pdcch_params->n_symb = (cset_idx < 2)? 1 : 2; - pdcch_params->rb_offset = (cset_idx&1)? 16 : 0; + pdcch_pdu->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1; + pdcch_pdu->n_rb = 96; + pdcch_pdu->n_symb = (cset_idx < 2)? 1 : 2; + pdcch_pdu->rb_offset = (cset_idx&1)? 16 : 0; break; case kHz120: AssertFatal(cset_idx<8,"Coreset index %d reserved for scs kHz240/kHz120\n", cset_idx); - pdcch_params->mux_pattern = (cset_idx < 4)? NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2; - pdcch_params->n_rb = (cset_idx < 4)? 48 : (cset_idx < 6)? 24 : 48; - pdcch_params->n_symb = ((cset_idx==2)||(cset_idx==3))? 2 : 1; - pdcch_params->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_240_120[cset_idx]>0)? nr_coreset_rb_offset_pdcch_type_0_scs_240_120[cset_idx] : + pdcch_pdu->mux_pattern = (cset_idx < 4)? NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 : NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2; + pdcch_pdu->n_rb = (cset_idx < 4)? 48 : (cset_idx < 6)? 24 : 48; + pdcch_pdu->n_symb = ((cset_idx==2)||(cset_idx==3))? 2 : 1; + pdcch_pdu->rb_offset = (nr_coreset_rb_offset_pdcch_type_0_scs_240_120[cset_idx]>0)? nr_coreset_rb_offset_pdcch_type_0_scs_240_120[cset_idx] : (k_ssb == 0)? -41 : -42; break; @@ -281,29 +344,29 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p } /// Search space params - switch(pdcch_params->mux_pattern) { + switch(pdcch_pdu->mux_pattern) { case NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1: if (freq_range == nr_FR1) { O = nr_ss_param_O_type_0_mux1_FR1[ss_idx]; - pdcch_params->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR1[ss_idx]; + pdcch_pdu->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR1[ss_idx]; M = nr_ss_param_M_type_0_mux1_FR1[ss_idx]; M_scale = nr_ss_scale_M_mux1_FR1[ss_idx]; - pdcch_params->first_symbol = (ss_idx < 8)? ( (ssb_idx&1)? pdcch_params->n_symb : 0 ) : nr_ss_first_symb_idx_type_0_mux1_FR1[ss_idx - 8]; + pdcch_pdu->first_symbol = (ss_idx < 8)? ( (ssb_idx&1)? pdcch_pdu->n_symb : 0 ) : nr_ss_first_symb_idx_type_0_mux1_FR1[ss_idx - 8]; } else { AssertFatal(ss_idx<14 ,"Invalid search space index for multiplexing type 1 and FR2 %d\n", ss_idx); O = nr_ss_param_O_type_0_mux1_FR2[ss_idx]; O_scale = nr_ss_scale_O_mux1_FR2[ss_idx]; - pdcch_params->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR2[ss_idx]; + pdcch_pdu->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR2[ss_idx]; M = nr_ss_param_M_type_0_mux1_FR2[ss_idx]; M_scale = nr_ss_scale_M_mux1_FR2[ss_idx]; - pdcch_params->first_symbol = (ss_idx < 12)? ( (ss_idx&1)? 7 : 0 ) : 0; + pdcch_pdu->first_symbol = (ss_idx < 12)? ( (ss_idx&1)? 7 : 0 ) : 0; } - pdcch_params->nb_slots = 2; - pdcch_params->sfn_mod2 = (CEILIDIV( (((O<>O_scale) + ((ssb_idx*M)>>M_scale)), nb_slots_per_frame ) & 1)? 1 : 0; - pdcch_params->first_slot = (((O<>O_scale) + ((ssb_idx*M)>>M_scale)) % nb_slots_per_frame; + pdcch_pdu->nb_slots = 2; + pdcch_pdu->sfn_mod2 = (CEILIDIV( (((O<>O_scale) + ((ssb_idx*M)>>M_scale)), nb_slots_per_frame ) & 1)? 1 : 0; + pdcch_pdu->first_slot = (((O<>O_scale) + ((ssb_idx*M)>>M_scale)) % nb_slots_per_frame; break; @@ -312,14 +375,14 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p "Invalid scs_common/pdcch_scs combination %d/%d for Mux type 2\n", scs_common, pdcch_scs ); AssertFatal(ss_idx==0, "Search space index %d reserved for scs_common/pdcch_scs combination %d/%d", ss_idx, scs_common, pdcch_scs); - pdcch_params->nb_slots = 1; + pdcch_pdu->nb_slots = 1; if ((scs_common==kHz120)&&(pdcch_scs==kHz60)) { - pdcch_params->first_symbol = nr_ss_first_symb_idx_scs_120_60_mux2[ssb_idx&3]; - // Missing in pdcch_params sfn_C and n_C here and in else case + pdcch_pdu->first_symbol = nr_ss_first_symb_idx_scs_120_60_mux2[ssb_idx&3]; + // Missing in pdcch_pdu sfn_C and n_C here and in else case } else { - pdcch_params->first_symbol = ((ssb_idx&7)==4)?12 : ((ssb_idx&7)==4)?13 : nr_ss_first_symb_idx_scs_240_120_set1_mux2[ssb_idx&7]; //??? + pdcch_pdu->first_symbol = ((ssb_idx&7)==4)?12 : ((ssb_idx&7)==4)?13 : nr_ss_first_symb_idx_scs_240_120_set1_mux2[ssb_idx&7]; //??? } break; @@ -329,212 +392,555 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p "Invalid scs_common/pdcch_scs combination %d/%d for Mux type 3\n", scs_common, pdcch_scs ); AssertFatal(ss_idx==0, "Search space index %d reserved for scs_common/pdcch_scs combination %d/%d", ss_idx, scs_common, pdcch_scs); - pdcch_params->first_symbol = nr_ss_first_symb_idx_scs_120_120_mux3[ssb_idx&3]; + pdcch_pdu->first_symbol = nr_ss_first_symb_idx_scs_120_120_mux3[ssb_idx&3]; break; default: - AssertFatal(1==0, "Invalid SSB and coreset multiplexing pattern %d\n", pdcch_params->mux_pattern); + AssertFatal(1==0, "Invalid SSB and coreset multiplexing pattern %d\n", pdcch_pdu->mux_pattern); } - pdcch_params->config_type = NFAPI_NR_CSET_CONFIG_MIB_SIB1; - pdcch_params->cr_mapping_type = NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED; - pdcch_params->precoder_granularity = NFAPI_NR_CSET_SAME_AS_REG_BUNDLE; - pdcch_params->reg_bundle_size = 6; - pdcch_params->interleaver_size = 2; + pdcch_pdu->config_type = NFAPI_NR_CSET_CONFIG_MIB_SIB1; + pdcch_pdu->cr_mapping_type = NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED; + pdcch_pdu->precoder_granularity = NFAPI_NR_CSET_SAME_AS_REG_BUNDLE; + pdcch_pdu->reg_bundle_size = 6; + pdcch_pdu->interleaver_size = 2; // set initial banwidth part to full bandwidth - pdcch_params->n_RB_BWP = N_RB; + pdcch_pdu->n_RB_BWP = N_RB; + */ } -void nr_configure_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, - nfapi_nr_coreset_t* coreset, - nfapi_nr_search_space_t* search_space, - nfapi_nr_config_request_t cfg, - uint16_t N_RB) { -/// coreset - - //ControlResourceSetId - pdcch_params->config_type = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; +void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, + int ss_type, + NR_ServingCellConfigCommon_t *scc, + NR_BWP_Downlink_t *bwp){ - //frequencyDomainResources - uint8_t count=0, start=0, start_set=0; - uint64_t bitmap = coreset->frequency_domain_resources; - - for (int i=0; i<45; i++) - if ((bitmap>>(44-i))&1) { - count++; - if (!start_set) { + if (bwp) { // This is not the InitialBWP + /// coreset + + //ControlResourceSetId + // pdcch_pdu->config_type = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL, + "controlResourceSetToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count>0, + "controlResourceSetToAddModList is empty\n"); + NR_ControlResourceSet_t *coreset0 = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[0]; + + + pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; + pdcch_pdu->CyclicPrefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix; + + pdcch_pdu->DurationSymbols = coreset0->duration; + + //frequencyDomainResources + /* uint8_t count=0, start=0, start_set=0; + // find coreset descriptor + + uint64_t bitmap = (((uint64_t)coreset0->frequencyDomainResources.buf[0])<<37)| + (((uint64_t)coreset0->frequencyDomainResources.buf[1])<<29)| + (((uint64_t)coreset0->frequencyDomainResources.buf[2])<<21)| + (((uint64_t)coreset0->frequencyDomainResources.buf[3])<<13)| + (((uint64_t)coreset0->frequencyDomainResources.buf[4])<<5)| + (((uint64_t)coreset0->frequencyDomainResources.buf[5])>>3); + + for (int i=0; i<45; i++) + if ((bitmap>>(44-i))&1) { + count++; + if (!start_set) { start = i; start_set = 1; + } + } + pdcch_pdu->rb_offset = 6*start; + pdcch_pdu->n_rb = 6*count; + */ + for (int i=0;i<6;i++) + pdcch_pdu->FreqDomainResource[i] = coreset0->frequencyDomainResources.buf[i]; + //duration + + + //cce-REG-MappingType + pdcch_pdu->CceRegMappingType = coreset0->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved? + NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED; + if (pdcch_pdu->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { + pdcch_pdu->RegBundleSize = (coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize); + pdcch_pdu->InterleaverSize = (coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize); + AssertFatal(scc->physCellId != NULL,"scc->physCellId is null\n"); + pdcch_pdu->ShiftIndex = coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex != NULL ? *coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex : *scc->physCellId; + } + else { + pdcch_pdu->RegBundleSize = 0; + pdcch_pdu->InterleaverSize = 0; + pdcch_pdu->ShiftIndex = 0; + } + + pdcch_pdu->CoreSetType = 1; + + //precoderGranularity + pdcch_pdu->precoderGranularity = coreset0->precoderGranularity; + + //TCI states + // + /* + //TCI present + if (coreset0->tci_PresentInDCI != NULL) { + AssertFatal(coreset0->tci_StatesPDCCH_ToAddList != NULL,"tci_StatesPDCCH_ToAddList is null\n"); + AssertFatal(coreset0->tci_StatesPDCCH_ToAddList->list.count>0,"TCI state list is empty\n"); + for (int i=0;itci_StatesPDCCH_ToAddList->list.count;i++) { + + } + */ + + for (int i=0;inumDlDci;i++) { + //pdcch-DMRS-ScramblingID + AssertFatal(coreset0->pdcch_DMRS_ScramblingID != NULL,"coreset0->pdcch_DMRS_ScramblingID is null\n"); + pdcch_pdu->ScramblingId[i] = *coreset0->pdcch_DMRS_ScramblingID; + } + + /// SearchSpace + + // first symbol + //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); + int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; + + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); + NR_SearchSpace_t *ss; + int found=0; + int target_ss = NR_SearchSpace__searchSpaceType_PR_common; + if (ss_type == 1) { + target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + } + + for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { + ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; + AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); + AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); + if (*ss->controlResourceSetId == coreset0->controlResourceSetId && + ss->searchSpaceType->present == target_ss) { + found=1; + break; } } - pdcch_params->rb_offset = 6*start; - pdcch_params->n_rb = 6*count; - - //duration - pdcch_params->n_symb = coreset->duration; - - //cce-REG-MappingType - pdcch_params->cr_mapping_type = coreset->cce_reg_mapping_type; - if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { - pdcch_params->reg_bundle_size = coreset->reg_bundle_size; - pdcch_params->interleaver_size = coreset->interleaver_size; - } - else { - pdcch_params->reg_bundle_size = 0; - pdcch_params->interleaver_size = 0; + AssertFatal(found==1,"Couldn't find a searchspace corresponding to coreset0\n"); + AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n"); + AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n"); + + // for SPS=14 8 MSBs in positions 13 downto 6, + uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | + (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + + for (int i=0; i>(sps-1-i))&1) { + pdcch_pdu->StartSymbolIndex=i; + break; + } } - //shift index - pdcch_params->shift_index = coreset->shift_index; - - //precoderGranularity - pdcch_params->precoder_granularity = coreset->precoder_granularity; - - //TCI states - // PDCCH params does not yet include information about TCI and QCL (needed for DCI 1.1 and 0.1) - - //pdcch-DMRS-ScramblingID - pdcch_params->scrambling_id = coreset->dmrs_scrambling_id; - - -/// SearchSpace - - // first symbol - //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); - for (int i=0; imonitoring_symbols_in_slot>>(31-i))&1) { - pdcch_params->first_symbol=i; - break; - } - - //searchSpaceType - pdcch_params->search_space_type = search_space->search_space_type; - - pdcch_params->n_RB_BWP = N_RB; + else { // this is for InitialBWP + AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n"); + } } -int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, - nfapi_nr_coreset_t coreset, - uint16_t frame, - uint16_t slot, - nfapi_nr_config_request_t cfg) { - AssertFatal(search_space.coreset_id==coreset.coreset_id, "Invalid association of coreset(%d) and search space(%d)\n", - search_space.search_space_id, coreset.coreset_id); - uint8_t is_dci_opportunity=0; - uint16_t Ks=search_space.slot_monitoring_periodicity; - uint16_t Os=search_space.slot_monitoring_offset; - uint8_t Ts=search_space.duration; +void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + dci_pdu_rel15_t *dci_pdu_rel15, + int *dci_formats, + int *rnti_types + ) { + + uint16_t N_RB = pdcch_pdu_rel15->BWPSize; + uint8_t fsize=0, pos=0; - if (((frame*get_spf(&cfg) + slot - Os)%Ks)numDlDci;d++) { + + uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->Payload[d]; + AssertFatal(pdcch_pdu_rel15->PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported"); + + int dci_size = pdcch_pdu_rel15->PayloadSizeBits[d]; + + /// Payload generation + switch(dci_formats[d]) { + case NR_DL_DCI_FORMAT_1_0: + switch(rnti_types[d]) { + case NR_RNTI_RA: + // Freq domain assignment + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos=fsize; + *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,N_RB,dci_size-pos,*dci_pdu); +#endif + // Time domain assignment + pos+=4; + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment&0xf) << (dci_size-pos)); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,dci_size-pos,*dci_pdu); +#endif + // VRB to PRB mapping + + pos++; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&0x1)<<(dci_size-pos); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,dci_size-pos,*dci_pdu); +#endif + // MCS + pos+=5; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); +#endif + // TB scaling + pos+=2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling&0x3)<<(dci_size-pos); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); +#endif + break; + + case NR_RNTI_C: + + // indicating a DL DCI format 1bit + pos++; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&1)<<(dci_size-pos); +#ifdef DEBUG_FILL_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; + *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment,fsize,dci_size-pos,*dci_pdu); +#endif + + uint16_t is_ra = 1; + for (int i=0; ifrequency_domain_assignment>>i)&1)) { + is_ra = 0; + break; + } + if (is_ra) //fsize are all 1 38.212 p86 + { + // ra_preamble_index 6 bits + pos+=6; + *dci_pdu |= ((dci_pdu_rel15->ra_preamble_index&0x3f)<<(dci_size-pos)); + + // UL/SUL indicator 1 bit + pos++; + *dci_pdu |= (dci_pdu_rel15->ul_sul_indicator&1)<<(dci_size-pos); + + // SS/PBCH index 6 bits + pos+=6; + *dci_pdu |= ((dci_pdu_rel15->ss_pbch_index&0x3f)<<(dci_size-pos)); + + // prach_mask_index 4 bits + pos+=4; + *dci_pdu |= ((dci_pdu_rel15->prach_mask_index&0xf)<<(dci_size-pos)); + + } //end if + + else { + + // Time domain assignment 4bit + + pos+=4; + *dci_pdu |= ((dci_pdu_rel15->time_domain_assignment&0xf) << (dci_size-pos)); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment,4,dci_size-pos,*dci_pdu); +#endif + + // VRB to PRB mapping 1bit + pos++; + *dci_pdu |= (dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping,1,dci_size-pos,*dci_pdu); +#endif + + // MCS 5bit //bit over 32, so dci_pdu ++ + pos+=5; + *dci_pdu |= (dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"MCS %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,5,dci_size-pos,*dci_pdu); +#endif + + // New data indicator 1bit + pos++; + *dci_pdu |= (dci_pdu_rel15->ndi&1)<<(dci_size-pos); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); +#endif + + // Redundancy version 2bit + pos+=2; + *dci_pdu |= (dci_pdu_rel15->rv&0x3)<<(dci_size-pos); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); +#endif + + // HARQ process number 4bit + pos+=4; + *dci_pdu |= ((dci_pdu_rel15->harq_pid&0xf)<<(dci_size-pos)); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); +#endif + + // Downlink assignment index 2bit + pos+=2; + *dci_pdu |= ((dci_pdu_rel15->dai&3)<<(dci_size-pos)); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"DAI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->dai,2,dci_size-pos,*dci_pdu); +#endif + + // TPC command for scheduled PUCCH 2bit + pos+=2; + *dci_pdu |= ((dci_pdu_rel15->tpc&3)<<(dci_size-pos)); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); +#endif + + // PUCCH resource indicator 3bit + pos+=3; + *dci_pdu |= ((dci_pdu_rel15->pucch_resource_indicator&0x7)<<(dci_size-pos)); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pucch_resource_indicator,3,dci_size-pos,*dci_pdu); +#endif + + // PDSCH-to-HARQ_feedback timing indicator 3bit + pos+=3; + *dci_pdu |= ((dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_size-pos)); +#ifdef DEBUG_FILL_DCI + LOG_D(MAC,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator,3,dci_size-pos,*dci_pdu); +#endif + + } //end else + break; + + case NR_RNTI_P: + + // Short Messages Indicator – 2 bits + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_size-pos++); + // Short Messages – 8 bits + for (int i=0; i<8; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->short_messages>>(7-i))&1)<<(dci_size-pos++); + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4 bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos++); + // MCS 5 bit + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + + // TB scaling 2 bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_size-pos++); + + + break; + + case NR_RNTI_SI: + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4 bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos++); + // MCS 5bit //bit over 32, so dci_pdu ++ + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + // Redundancy version 2bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++); + + break; + + case NR_RNTI_TC: + // indicating a DL DCI format 1bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&1)<<(dci_size-pos++); + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4 bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping&1)<<(dci_size-pos++); + // MCS 5bit //bit over 32, so dci_pdu ++ + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + // New data indicator 1bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi&1)<<(dci_size-pos++); + // Redundancy version 2bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++); + // HARQ process number 4bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->harq_pid>>(3-i))&1)<<(dci_size-pos++); + + // Downlink assignment index – 2 bits + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->dai>>(1-i))&1)<<(dci_size-pos++); + + // TPC command for scheduled PUCCH – 2 bits + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc>>(1-i))&1)<<(dci_size-pos++); + + + // LOG_D(MAC, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n", + // dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]); + + + // PDSCH-to-HARQ_feedback timing indicator – 3 bits + for (int i=0; i<3; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_size-pos++); + + break; + } + break; + + case NR_UL_DCI_FORMAT_0_0: + switch(rnti_types[d]) + { + case NR_RNTI_C: + // indicating a DL DCI format 1bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&1)<<(dci_size-pos++); + // Freq domain assignment max 16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // Frequency hopping flag – 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag&1)<<(dci_size-pos++); + // MCS 5 bit + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + // New data indicator 1bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi&1)<<(dci_size-pos++); + // Redundancy version 2bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++); + // HARQ process number 4bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->harq_pid>>(3-i))&1)<<(dci_size-pos++); + + // TPC command for scheduled PUSCH – 2 bits + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc>>(1-i))&1)<<(dci_size-pos++); + + // Padding bits + for(int a = pos;a<32;a++) + *dci_pdu |= ((uint64_t)dci_pdu_rel15->padding&1)<<(dci_size-pos++); + + // 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_rel15->ul_sul_indicator&1)<<(dci_size-pos++); + */ + break; + + case NFAPI_NR_RNTI_TC: + + // indicating a DL DCI format 1bit + *dci_pdu |= (dci_pdu_rel15->format_indicator&1)<<(dci_size-pos++); + // Freq domain assignment max 16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + for (int i=0; ifrequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++); + // Time domain assignment 4bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++); + // Frequency hopping flag – 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag&1)<<(dci_size-pos++); + // MCS 5 bit + for (int i=0; i<5; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++); + // New data indicator 1bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi&1)<<(dci_size-pos++); + // Redundancy version 2bit + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++); + // HARQ process number 4bit + for (int i=0; i<4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->harq_pid>>(3-i))&1)<<(dci_size-pos++); + + // TPC command for scheduled PUSCH – 2 bits + for (int i=0; i<2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc>>(1-i))&1)<<(dci_size-pos++); + + // Padding bits + for(int a = pos;a<32;a++) + *dci_pdu |= ((uint64_t)dci_pdu_rel15->padding&1)<<(dci_size-pos++); + + // UL/SUL indicator – 1 bit + /* + commented for now (RK): need to get this information from BWP descriptor + if (cfg->pucch_config.pucch_GroupHopping.value) + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ul_sul_indicator&1)<<(dci_size-pos++); + */ + break; + + } + break; + } + } +} + + + /* + int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, + nfapi_nr_coreset_t coreset, + uint16_t frame, + uint16_t slot, + nfapi_nr_config_request_scf_t cfg) { + + AssertFatal(search_space.coreset_id==coreset.coreset_id, "Invalid association of coreset(%d) and search space(%d)\n", + search_space.search_space_id, coreset.coreset_id); + + uint8_t is_dci_opportunity=0; + uint16_t Ks=search_space.slot_monitoring_periodicity; + uint16_t Os=search_space.slot_monitoring_offset; + uint8_t Ts=search_space.duration; + + if (((frame*get_spf(&cfg) + slot - Os)%Ks)rf_config.dl_subcarrierspacing.value); -} - - -int get_ulscs(nfapi_nr_config_request_t *cfg) { - - return(cfg->rf_config.ul_subcarrierspacing.value); -} - -int get_spf(nfapi_nr_config_request_t *cfg) { - - int mu = cfg->rf_config.dl_subcarrierspacing.value; + int mu = cfg->ssb_config.scs_common.value; AssertFatal(mu>=0&&mu<4,"Illegal scs %d\n",mu); return(10 * (1<subframe_config.dl_cyclic_prefix_type.value==NFAPI_CP_EXTENDED)?12:14); - -} - - -extern uint16_t nr_tbs_table[93]; - -void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu) { - - LOG_D(MAC, "TBS calculation\n"); - - nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15; - uint8_t rnti_type = params_rel15.rnti_type; - uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \ - (dlsch_rel15->x_overhead); - uint8_t N_PRB_DMRS = (dlsch_rel15->dmrs_Type==1)?6:4; //This only works for antenna port 1000 - uint8_t N_sh_symb = dlsch_rel15->nb_symbols; - uint8_t Imcs = dlsch_rel15->mcs_idx; - 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); - - uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R; - uint8_t table_idx, Qm, n, scale; - - //uint8_t mcs_table = config.pdsch_config.mcs_table.value; - //uint8_t ss_type = params_rel15.search_space_type; - //uint8_t dci_format = params_rel15.dci_format; - //get_table_idx(mcs_table, dci_format, rnti_type, ss_type); - table_idx = 1; - scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10; - - N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb; - R = nr_get_code_rate(Imcs, table_idx); - Qm = nr_get_Qm(Imcs, table_idx); - Ninfo = (N_RE*R*Qm*dlsch_rel15->nb_layers)>>scale; - - if (Ninfo <= 3824) { - n = max(3, (log2(Ninfo)-6)); - Ninfo_prime = max(24, (Ninfo>>n)<= Ninfo_prime) { - TBS = nr_tbs_table[i]; - break; - } - } - else { - n = log2(Ninfo-24)-5; - Ninfo_prime = max(3840, (ROUNDIDIV((Ninfo-24),(1<8424) { - C = CEILIDIV((Ninfo_prime+24),8424); - TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24; - } - else - TBS = ((CEILIDIV((Ninfo_prime+24),8))<<3) - 24; - } - } - - dlsch_rel15->coding_rate = R; - dlsch_rel15->modulation_order = Qm; - dlsch_rel15->transport_block_size = TBS; - dlsch_rel15->nb_mod_symbols = N_RE_prime*dlsch_rel15->n_prb*dlsch_rel15->nb_codewords; - - LOG_D(MAC, "TBS %d : N_RE %d N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d nb_symbols %d\n", - TBS, N_RE, N_PRB_DMRS, N_sh_symb, N_PRB_oh, Ninfo, Ninfo_prime, R, Qm, table_idx, scale, dlsch_rel15->nb_mod_symbols); -} int extract_startSymbol(int startSymbolAndLength) { int tmp = startSymbolAndLength/14; @@ -622,7 +1028,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ int UE_id; - int i, j; + int i; NR_UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list; LOG_I(MAC, "[gNB %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", mod_idP, @@ -658,13 +1064,13 @@ int add_new_nr_ue(module_id_t mod_idP, return -1; } -void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, +/*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, nfapi_nr_coreset_t *coreset, nfapi_nr_search_space_t *search_space) { nfapi_nr_coreset_t *cs; nfapi_nr_search_space_t *ss; - + NR_ServingCellConfigCommon_t *scc=cg->spCellConfig->reconfigurationWithSync->spCellConfigCommon; AssertFatal(cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList has %d BWP!\n", cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); @@ -680,7 +1086,7 @@ void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, cs->coreset_id = coreset_i->controlResourceSetId; AssertFatal(coreset_i->frequencyDomainResources.size <=8 && coreset_i->frequencyDomainResources.size>0, "coreset_i->frequencyDomainResources.size=%d\n", - coreset_i->frequencyDomainResources.size); + (int)coreset_i->frequencyDomainResources.size); for (int f=0;ffrequencyDomainResources.size;f++) ((uint8_t*)&cs->frequency_domain_resources)[coreset_i->frequencyDomainResources.size-1-f]=coreset_i->frequencyDomainResources.buf[f]; @@ -796,11 +1202,11 @@ void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, AssertFatal(searchSpace_i->monitoringSymbolsWithinSlot->size == 2, "ss_i->monitoringSymbolsWithinSlot = %d != 2\n", - searchSpace_i->monitoringSymbolsWithinSlot->size); + (int)searchSpace_i->monitoringSymbolsWithinSlot->size); ((uint8_t*)&ss->monitoring_symbols_in_slot)[1] = searchSpace_i->monitoringSymbolsWithinSlot->buf[0]; ((uint8_t*)&ss->monitoring_symbols_in_slot)[0] = searchSpace_i->monitoringSymbolsWithinSlot->buf[1]; - AssertFatal(searchSpace_i->nrofCandidates!=NULL,"searchSpace_%d->nrofCandidates is null\n",searchSpace_i->searchSpaceId); + AssertFatal(searchSpace_i->nrofCandidates!=NULL,"searchSpace_%d->nrofCandidates is null\n",(int)searchSpace_i->searchSpaceId); if (searchSpace_i->nrofCandidates->aggregationLevel1 == NR_SearchSpace__nrofCandidates__aggregationLevel1_n8) ss->number_of_candidates[0] = 8; else ss->number_of_candidates[0] = searchSpace_i->nrofCandidates->aggregationLevel1; @@ -818,9 +1224,9 @@ void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, else ss->number_of_candidates[4] = searchSpace_i->nrofCandidates->aggregationLevel16; AssertFatal(searchSpace_i->searchSpaceType->present==NR_SearchSpace__searchSpaceType_PR_common, - "searchspace %d is not common\n",searchSpace_i->searchSpaceId); + "searchspace %d is not common\n",(int)searchSpace_i->searchSpaceId); AssertFatal(searchSpace_i->searchSpaceType->choice.common!=NULL, - "searchspace %d common is null\n",searchSpace_i->searchSpaceId); + "searchspace %d common is null\n",(int)searchSpace_i->searchSpaceId); ss->search_space_type = NFAPI_NR_SEARCH_SPACE_TYPE_COMMON; if (searchSpace_i->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0) ss->css_formats_0_0_and_1_0 = 1; @@ -915,11 +1321,11 @@ void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, AssertFatal(searchSpace_i->monitoringSymbolsWithinSlot->size == 2, "ss_i->monitoringSymbolsWithinSlot = %d != 2\n", - searchSpace_i->monitoringSymbolsWithinSlot->size); + (int)searchSpace_i->monitoringSymbolsWithinSlot->size); ((uint8_t*)&ss->monitoring_symbols_in_slot)[1] = searchSpace_i->monitoringSymbolsWithinSlot->buf[0]; ((uint8_t*)&ss->monitoring_symbols_in_slot)[0] = searchSpace_i->monitoringSymbolsWithinSlot->buf[1]; - AssertFatal(searchSpace_i->nrofCandidates!=NULL,"searchSpace_%d->nrofCandidates is null\n",searchSpace_i->searchSpaceId); + AssertFatal(searchSpace_i->nrofCandidates!=NULL,"searchSpace_%d->nrofCandidates is null\n",(int)searchSpace_i->searchSpaceId); if (searchSpace_i->nrofCandidates->aggregationLevel1 == NR_SearchSpace__nrofCandidates__aggregationLevel1_n8) ss->number_of_candidates[0] = 8; else ss->number_of_candidates[0] = searchSpace_i->nrofCandidates->aggregationLevel1; @@ -960,3 +1366,9 @@ void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg, } } } +*/ + + + + + diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index d811484c16..3c1573fe27 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -34,26 +34,31 @@ #include "nr_mac_gNB.h" #include "PHY/defs_gNB.h" +void set_cset_offset(uint16_t); + void mac_top_init_gNB(void); void config_common(int Mod_idP, + int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc ); int rrc_mac_config_req_gNB(module_id_t Mod_idP, int ssb_SubcarrierOffset, + int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc, int nsa_flag, uint32_t rnti, NR_CellGroupConfig_t *secondaryCellGroup ); -int is_nr_UL_slot(NR_COMMON_channels_t * ccP, int slotP); void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, frame_t frameP, sub_frame_t subframeP); -void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); +void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, + frame_t frame_txP, sub_frame_t slot_txP, + frame_t frame_rxP, sub_frame_t slot_rxP); void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); @@ -61,11 +66,25 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); +int configure_fapi_dl_Tx(int Mod_id, + int *CCEIndeces, + nfapi_nr_dl_tti_request_body_t *dl_req, + nfapi_nr_pdu_t *TX_req, + uint8_t *mcsIndex, + uint16_t *rbSize, + uint16_t *rbStart); + +void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types); void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP); + sub_frame_t slotP, + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config); -void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, +void nr_schedule_uss_ulsch_phytest(int Mod_idP, + frame_t frameP, + sub_frame_t slotP); + +void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, nr_scs_e scs_common, nr_scs_e pdcch_scs, nr_frequency_range_e freq_range, @@ -76,38 +95,43 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* p uint8_t n_ssb, uint16_t nb_slots_per_frame, uint16_t N_RB); - +/* int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, nfapi_nr_coreset_t coreset, uint16_t frame, uint16_t slot, - nfapi_nr_config_request_t cfg); + nfapi_nr_config_request_scf_t cfg); +*/ +void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, + int ss_type, + NR_ServingCellConfigCommon_t *scc, + NR_BWP_Downlink_t *bwp); +void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + dci_pdu_rel15_t *dci_pdu_rel15, + int *dci_formats, + int *rnti_types + ); -void nr_configure_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params, - nfapi_nr_coreset_t* coreset, - nfapi_nr_search_space_t* search_space, - nfapi_nr_config_request_t cfg, - uint16_t N_RB); +int get_spf(nfapi_nr_config_request_scf_t *cfg); -int get_dlscs(nfapi_nr_config_request_t *cfg); +int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot); -int get_ulscs(nfapi_nr_config_request_t *cfg); - -int get_spf(nfapi_nr_config_request_t *cfg); - -int to_absslot(nfapi_nr_config_request_t *cfg,int frame,int slot); - -int get_symbolsperslot(nfapi_nr_config_request_t *cfg); - -void get_band(uint32_t downlink_frequency, uint8_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); +void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); uint64_t from_nrarfcn(int nr_bandP, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint32_t bw); -void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu, - nfapi_nr_dl_config_dci_dl_pdu dci_pdu); +void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, + int x_overhead); +/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */ +uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx); +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); + +/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */ +uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx); +uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); int NRRIV2BW(int locationAndBandwidth,int N_RB); @@ -124,4 +148,24 @@ find_nr_UE_id(module_id_t mod_idP, int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP); +int get_num_dmrs(uint16_t dmrs_mask ); + +int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols); + +uint16_t nr_dci_size(nr_dci_format_t format, + nr_rnti_type_t rnti_type, + uint16_t N_RB); + +int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, + int bwp_id, + int coreset_id, + int aggregation, + int search_space, // 0 common, 1 ue-specific + int UE_id, + int m + ); + +int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); +int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 0266e6617e..8c2d66af47 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -40,13 +40,14 @@ //#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "common/ran_context.h" +#include "executables/nr-softmodem.h" extern RAN_CONTEXT_t RC; void mac_top_init_gNB(void) { - module_id_t i,j; + module_id_t i; int list_el; NR_UE_list_t *UE_list; gNB_MAC_INST *nrmac; @@ -54,7 +55,7 @@ void mac_top_init_gNB(void) LOG_I(MAC, "[MAIN] Init function start:nb_nr_macrlc_inst=%d\n",RC.nb_nr_macrlc_inst); if (RC.nb_nr_macrlc_inst > 0) { - + RC.nrmac = (gNB_MAC_INST **) malloc16(RC.nb_nr_macrlc_inst *sizeof(gNB_MAC_INST *)); AssertFatal(RC.nrmac != NULL,"can't ALLOCATE %zu Bytes for %d gNB_MAC_INST with size %zu \n", @@ -73,30 +74,16 @@ void mac_top_init_gNB(void) bzero(RC.nrmac[i], sizeof(gNB_MAC_INST)); RC.nrmac[i]->Mod_id = i; - - - for (j = 0; j < MAX_NUM_CCs; j++) { - RC.nrmac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.nrmac[i]->dl_config_pdu_list[j]; - RC.nrmac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = RC.nrmac[i]->ul_config_pdu_list[j]; - - for (int k = 0; k < 10; k++) - RC.nrmac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list =RC.nrmac[i]->ul_config_pdu_list_tmp[j][k]; - - RC.nrmac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.nrmac[i]->hi_dci0_pdu_list[j]; - RC.nrmac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.nrmac[i]->tx_request_pdu[j]; - RC.nrmac[i]->ul_handle = 0; - - - } - - }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) - - AssertFatal(rlc_module_init() == 0,"Could not initialize RLC layer\n"); - + + AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); + // These should be out of here later pdcp_layer_init(); + if(IS_SOFTMODEM_NOS1) + nr_ip_over_LTE_DRB_preconfiguration(); + rrc_init_nr_global_param(); }else { @@ -105,7 +92,7 @@ void mac_top_init_gNB(void) // Initialize Linked-List for Active UEs for (i = 0; i < RC.nb_nr_macrlc_inst; i++) { - + nrmac = RC.nrmac[i]; nrmac->if_inst = NR_IF_Module_init(i); @@ -126,4 +113,5 @@ void mac_top_init_gNB(void) UE_list->active[list_el] = FALSE; } + srand48(0); } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c new file mode 100644 index 0000000000..e6127fb57e --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c @@ -0,0 +1,152 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* file: nr_compute_tbs.c + purpose: Compute NR TBS + author: Hongzhi WANG (TCL) +*/ +#define INDEX_MAX_TBS_TABLE (93) + +#include "common/utils/nr/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}; + +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_oh, + uint8_t Nl) +{ + + 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; + + 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; + + if (Ninfo <=3824) { + n = max(3, floor(log2(Ninfo)) - 6); + Np_info = max(24, (Ninfo>>n)<= Np_info){ + nr_tbs = Tbstable_nr[i]; + break; + } + } + } + else { + n = log2(Ninfo-24)-5; + Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 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; +} + + +//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) +{ + + uint16_t R, nb_re; + uint16_t nb_rb_lbrm=0; + uint8_t Qm; + int i; + uint32_t nr_tbs=0; + uint32_t Ninfo, Np_info; + uint8_t n; + + for (i=0; i<7; i++) { + if (NPRB_LBRM[i] >= nb_rb){ + nb_rb_lbrm = NPRB_LBRM[i]; + break; + } + } + + Qm = ((table == 1)? 8 : 6); + R = 948; + nb_re = 156 * nb_rb_lbrm; + + // Intermediate number of information bits + Ninfo = (nb_re * R * Qm * Nl)>>10; + + if (Ninfo <=3824) { + n = max(3, floor(log2(Ninfo)) - 6); + Np_info = max(24, (Ninfo>>n)<= Np_info){ + nr_tbs = Tbstable_nr[i]; + break; + } + } + } + else { + n = log2(Ninfo-24)-5; + Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 8424){ + nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24; + } + else { + nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24; + } + + } + + } + return nr_tbs; + +} diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c b/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c index 9c1ebf2115..bbaf1d705d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c @@ -20,7 +20,7 @@ */ /*! \file nr_mac_common.c - * \brief Common MAC functions for NR UE and gNB + * \brief Common MAC/PHY functions for NR UE and gNB * \author Florian Kaltenberger and Raymond Knopp * \date 2019 * \version 0.1 @@ -69,36 +69,46 @@ nr_bandentry_t nr_bandtable[] = { #define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) -void get_band(uint32_t downlink_frequency, - uint8_t *current_band, +void get_band(uint64_t downlink_frequency, + uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type) { int ind; - int64_t dl_freq_khz = downlink_frequency/1000; + uint64_t center_frequency_khz; + uint64_t center_freq_diff_khz; + uint64_t dl_freq_khz = downlink_frequency/1000; + + center_freq_diff_khz = 999999999999999999; // 2^64 + *current_band = 0; + for ( ind=0; ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]); ind++) { - *current_band = nr_bandtable[ind].band; - LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", ind, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min); + LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min); if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) { - *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000; - if (*current_offset == 0) - *current_type = TDD; - else - *current_type = FDD; - LOG_I( PHY, "DL frequency %"PRIu32": band %d, frame_type %d, UL frequency %"PRIu32"\n", - downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset); - break; + center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2; + if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){ + *current_band = nr_bandtable[ind].band; + *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000; + center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz); + + if (*current_offset == 0) + *current_type = TDD; + else + *current_type = FDD; + } } } - AssertFatal(ind != (sizeof(nr_bandtable) / sizeof(nr_bandtable[0])), - "Can't find EUTRA band for frequency %d\n", downlink_frequency); + LOG_I( PHY, "DL frequency %"PRIu64": band %d, frame_type %d, UL frequency %"PRIu64"\n", + downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset); + AssertFatal(*current_band != 0, + "Can't find EUTRA band for frequency %lu\n", downlink_frequency); } uint32_t to_nrarfcn(int nr_bandP, @@ -148,7 +158,12 @@ uint64_t from_nrarfcn(int nr_bandP, for (i = 0; i < 31 && nr_bandtable[i].band != nr_bandP; i++); AssertFatal(dl_nrarfcn>=nr_bandtable[i].N_OFFs_DL,"dl_nrarfcn %u < N_OFFs_DL %llu\n",dl_nrarfcn, (long long unsigned int)nr_bandtable[i].N_OFFs_DL); - LOG_I(PHY,"Computing dl_frequency (pointA %d => %llu (dlmin %llu, nr_bandtable[%d].N_OFFs_DL %d))\n",dl_nrarfcn,1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal),nr_bandtable[i].dl_min,i,nr_bandtable[i].N_OFFs_DL); + LOG_I(PHY,"Computing dl_frequency (pointA %llu => %llu (dlmin %llu, nr_bandtable[%d].N_OFFs_DL %llu))\n", + (unsigned long long)dl_nrarfcn, + (unsigned long long)(1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal)), + (unsigned long long)nr_bandtable[i].dl_min, + i, + (unsigned long long)nr_bandtable[i].N_OFFs_DL); return 1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal); } @@ -164,3 +179,419 @@ int32_t get_nr_uldl_offset(int nr_bandP) return (nr_bandtable[i].dl_min - nr_bandtable[i].ul_min); } + +void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, + int x_overhead) { + + LOG_D(MAC, "TBS calculation\n"); + + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_rel15 = &pdsch_pdu->pdsch_pdu_rel15; + uint16_t N_PRB_oh = x_overhead; + uint8_t N_PRB_DMRS = (pdsch_rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000 + uint8_t N_sh_symb = pdsch_rel15->NrOfSymbols; + uint8_t Imcs = pdsch_rel15->mcsIndex[0]; + uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh; + 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); + + uint16_t R; + uint32_t TBS=0; + uint8_t table_idx, Qm; + + /*uint8_t mcs_table = config.pdsch_config.mcs_table.value; + uint8_t ss_type = params_rel15.search_space_type; + uint8_t dci_format = params_rel15.dci_format; + get_table_idx(mcs_table, dci_format, rnti_type, ss_type);*/ + table_idx = 0; + R = nr_get_code_rate_dl(Imcs, table_idx); + Qm = nr_get_Qm_dl(Imcs, table_idx); + + TBS = nr_compute_tbs(Qm, + R, + pdsch_rel15->rbSize, + N_sh_symb, + N_PRB_DMRS, + N_PRB_oh, + pdsch_rel15->nrOfLayers)>>3; + + pdsch_rel15->targetCodeRate[0] = R; + pdsch_rel15->qamModOrder[0] = Qm; + pdsch_rel15->TBSize[0] = TBS; + // pdsch_rel15->nb_mod_symbols = N_RE_prime*pdsch_rel15->n_prb*pdsch_rel15->nb_codewords; + pdsch_rel15->mcsTable[0] = table_idx; + + LOG_D(MAC, "TBS %d bytes: N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d R %d Qm %d table %d nb_symbols %d\n", + TBS, N_PRB_DMRS, N_sh_symb, N_PRB_oh, R, Qm, table_idx,N_RE_prime*pdsch_rel15->rbSize*pdsch_rel15->NrOfCodewords ); +} + +//Table 5.1.3.1-1 of 38.214 +uint16_t Table_51311[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, + {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; + +//Table 5.1.3.1-2 of 38.214 +// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point +uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{6,466},{6,517},{6,567},{6,616},{6,666}, + {6,719},{6,772},{6,822},{6,873},{8,1365},{8,711},{8,754},{8,797},{8,841},{8,885},{8,1833},{8,948}}; + +//Table 5.1.3.1-3 of 38.214 +uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340}, + {4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}}; + +//Table 6.1.4.1-1 of 38.214 TODO fix for tp-pi2BPSK +uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, + {4,658},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; + +//Table 6.1.4.1-2 of 38.214 TODO fix for tp-pi2BPSK +uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679}, + {4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}}; + + + +uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { + switch(table_idx) { + case 0: + return (Table_51311[Imcs][0]); + break; + + case 1: + return (Table_51312[Imcs][0]); + break; + + case 2: + return (Table_51313[Imcs][0]); + break; + + default: + AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx); + } +} + +uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { + switch(table_idx) { + case 0: + return (Table_51311[Imcs][1]); + break; + + case 1: + return (Table_51312[Imcs][1]); + break; + + case 2: + return (Table_51313[Imcs][1]); + break; + + default: + AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx); + } +} + +uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { + switch(table_idx) { + case 0: + return (Table_51311[Imcs][0]); + break; + + case 1: + return (Table_51312[Imcs][0]); + break; + + case 2: + return (Table_51313[Imcs][0]); + break; + + case 3: + return (Table_61411[Imcs][0]); + break; + + case 4: + return (Table_61412[Imcs][0]); + break; + + default: + AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx); + } +} + +uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { + switch(table_idx) { + case 0: + return (Table_51311[Imcs][1]); + break; + + case 1: + return (Table_51312[Imcs][1]); + break; + + case 2: + return (Table_51313[Imcs][1]); + break; + + case 3: + return (Table_61411[Imcs][1]); + break; + + case 4: + return (Table_61412[Imcs][1]); + break; + + default: + AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx); + } +} + +static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) { + return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1)); +} + +static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8_t rnti_type, uint8_t ss_type) { + if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1) && ((rnti_type==NFAPI_NR_RNTI_C)||(rnti_type==NFAPI_NR_RNTI_CS))) + return 2; + else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type!=NFAPI_NR_RNTI_new) && (rnti_type==NFAPI_NR_RNTI_C) && (ss_type==NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)) + return 3; + else if (rnti_type==NFAPI_NR_RNTI_new) + return 3; + else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (rnti_type==NFAPI_NR_RNTI_CS) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1)) + return 2; // Condition mcs_table not configured in sps_config necessary here but not yet implemented + /*else if((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type==NFAPI_NR_RNTI_CS)) + * table_idx = 3; + * Note: the commented block refers to the case where the mcs_table is from sps_config*/ + else + return 1; +} + +int get_num_dmrs(uint16_t dmrs_mask ) { + + int num_dmrs=0; + + for (int i=0;i<16;i++) num_dmrs+=((dmrs_mask>>i)&1); + return(num_dmrs); +} + +uint16_t nr_dci_size(nr_dci_format_t format, + nr_rnti_type_t 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 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_dci_size(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 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 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 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 NR_DL_DCI_FORMAT_2_0: + break; + + case NR_DL_DCI_FORMAT_2_1: + break; + + case NR_DL_DCI_FORMAT_2_2: + break; + + case NR_DL_DCI_FORMAT_2_3: + break; + + default: + AssertFatal(1==0, "Invalid NR DCI format %d\n", format); + } + + return size; +} + +int tdd_period_to_num[8] = {500,625,1000,1250,2000,2500,5000,10000}; + +int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { + + int period,period1,period2=0; + + if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1); + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530) + period1 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period1 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity]; + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) { + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530) + period2 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period2 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity]; + } + period = period1+period2; + int scs=scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; + int slots=period*(1<tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0); + else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); +} + +int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) { + + int period,period1,period2=0; + + if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1); + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530) + period1 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period1 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity]; + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) { + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530) + period2 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period2 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity]; + } + period = period1+period2; + int scs=scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; + int slots=period*(1<= scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0); + else return(slot_in_period >= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); +} + +int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols) { + + int l0; + if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0=2; + else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0=3; + else AssertFatal(1==0,"Illegal dmrs_TypeA_Position %d\n",(int)dmrs_TypeA_Position); + if (pdsch_Config == NULL) { // Initial BWP + return(1<dmrs_DownlinkForPDSCH_MappingTypeA && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) { + // Relative to start of slot + NR_DMRS_DownlinkConfig_t *dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; + AssertFatal(NrOfSymbols>1 && NrOfSymbols < 15,"Illegal NrOfSymbols %d\n",NrOfSymbols); + int pos2=0; + if (dmrs_config->maxLength == NULL) { + // this is Table 7.4.1.1.2-3: PDSCH DM-RS positions l for single-symbol DM-RS + if (dmrs_config->dmrs_AdditionalPosition == NULL) pos2=1; + else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition == NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0 ) + return(1<dmrs_AdditionalPosition); + break; + case 8 : + case 9: + return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) + return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) + return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3) + return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) + return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3) + return(1<3,"Illegal NrOfSymbols %d for len2 DMRS\n",NrOfSymbols); + if (NrOfSymbols < 10) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_DownlinkForPDSCH_MappingTypeB && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) { + // Relative to start of PDSCH resource + AssertFatal(1==0,"TypeB DMRS not supported yet\n"); + } + } + AssertFatal(1==0,"Shouldn't get here\n"); + return(-1); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h new file mode 100644 index 0000000000..9bca4e669c --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h @@ -0,0 +1,62 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file mac.h +* \brief MAC data structures, constant, and function prototype +* \author Navid Nikaein and Raymond Knopp, WIE-TAI CHEN +* \date Dec. 2019 +* \version 0.1 +* \company Eurecom +* \email raymond.knopp@eurecom.fr + +*/ + +#ifndef __LAYER2_NR_MAC_COMMON_H__ +#define __LAYER2_NR_MAC_COMMON_H__ + +typedef enum { + NR_DL_DCI_FORMAT_1_0 = 0, + NR_DL_DCI_FORMAT_1_1, + NR_DL_DCI_FORMAT_2_0, + NR_DL_DCI_FORMAT_2_1, + NR_DL_DCI_FORMAT_2_2, + NR_DL_DCI_FORMAT_2_3, + NR_UL_DCI_FORMAT_0_0, + NR_UL_DCI_FORMAT_0_1 +} nr_dci_format_t; + +typedef enum { + NR_RNTI_new = 0, + NR_RNTI_C, + NR_RNTI_RA, + NR_RNTI_P, + NR_RNTI_CS, + NR_RNTI_TC, + NR_RNTI_SP_CSI, + NR_RNTI_SI, + NR_RNTI_SFI, + NR_RNTI_INT, + NR_RNTI_TPC_PUSCH, + NR_RNTI_TPC_PUCCH, + NR_RNTI_TPC_SRS +} nr_rnti_type_t; + +#endif diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 309ea2151c..18bc034ae4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -47,7 +47,7 @@ #include "NR_ServingCellConfigCommon.h" #include "NR_MeasConfig.h" -#include "nfapi_nr_interface.h" +#include "nfapi_nr_interface_scf.h" #include "NR_PHY_INTERFACE/NR_IF_Module.h" #include "COMMON/platform_constants.h" @@ -59,40 +59,45 @@ #include "PHY/TOOLS/time_meas.h" #include "targets/ARCH/COMMON/common_lib.h" +#include "nr_mac_common.h" + +#define MAX_NUM_BWP 2 +#define MAX_NUM_CORESET 2 +#define MAX_NUM_CCE 90 /*! \brief gNB common channels */ typedef struct { - int physCellId; - int p_gNB; - int Ncp; - int nr_band; - uint32_t dl_CarrierFreq; - NR_BCCH_BCH_Message_t *mib; - NR_TDD_UL_DL_ConfigCommon_t *tdd_Config; - NR_ARFCN_ValueEUTRA_t ul_CarrierFreq; - long ul_Bandwidth; - /// Outgoing MIB PDU for PHY - MIB_PDU MIB_pdu; - /// Outgoing BCCH pdu for PHY - BCCH_PDU BCCH_pdu; - /// Outgoing BCCH DCI allocation - uint32_t BCCH_alloc_pdu; - /// Outgoing CCCH pdu for PHY - CCCH_PDU CCCH_pdu; - /// Outgoing PCCH DCI allocation - uint32_t PCCH_alloc_pdu; - /// Outgoing PCCH pdu for PHY - PCCH_PDU PCCH_pdu; - /// Outgoing RAR pdu for PHY - RAR_PDU RAR_pdu; - /// Template for RA computations - RA_t ra[NB_RA_PROC_MAX]; - /// VRB map for common channels - uint8_t vrb_map[100]; - /// VRB map for common channels and retransmissions by PHICH - uint8_t vrb_map_UL[100]; - /// number of subframe allocation pattern available for MBSFN sync area - uint8_t num_sf_allocation_pattern; + int physCellId; + int p_gNB; + int Ncp; + int nr_band; + uint64_t dl_CarrierFreq; + NR_BCCH_BCH_Message_t *mib; + NR_ServingCellConfigCommon_t *ServingCellConfigCommon; + NR_ARFCN_ValueEUTRA_t ul_CarrierFreq; + long ul_Bandwidth; + /// Outgoing MIB PDU for PHY + MIB_PDU MIB_pdu; + /// Outgoing BCCH pdu for PHY + BCCH_PDU BCCH_pdu; + /// Outgoing BCCH DCI allocation + uint32_t BCCH_alloc_pdu; + /// Outgoing CCCH pdu for PHY + CCCH_PDU CCCH_pdu; + /// Outgoing PCCH DCI allocation + uint32_t PCCH_alloc_pdu; + /// Outgoing PCCH pdu for PHY + PCCH_PDU PCCH_pdu; + /// Outgoing RAR pdu for PHY + RAR_PDU RAR_pdu; + /// Template for RA computations + RA_t ra[NB_RA_PROC_MAX]; + /// VRB map for common channels + uint8_t vrb_map[100]; + /// VRB map for common channels and retransmissions by PHICH + uint8_t vrb_map_UL[100]; + /// number of subframe allocation pattern available for MBSFN sync area + uint8_t num_sf_allocation_pattern; } NR_COMMON_channels_t; /*! \brief scheduling control information set through an API (not used)*/ @@ -115,12 +120,6 @@ typedef struct { boolean_t active[MAX_MOBILES_PER_GNB]; rnti_t rnti[MAX_MOBILES_PER_GNB]; NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB]; - /// NFAPI coreset structure - nfapi_nr_coreset_t coreset[MAX_MOBILES_PER_GNB][NFAPI_NR_MAX_NB_CORESETS]; - /// NFAPI search space structure - nfapi_nr_search_space_t search_space[MAX_MOBILES_PER_GNB][NFAPI_NR_MAX_NB_SEARCH_SPACES]; - - } NR_UE_list_t; /*! \brief top level eNB MAC structure */ @@ -143,27 +142,15 @@ typedef struct gNB_MAC_INST_s { uint16_t pdu_index[NFAPI_CC_MAX]; /// NFAPI Config Request Structure - nfapi_nr_config_request_t config[NFAPI_CC_MAX]; + nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX]; /// NFAPI DL Config Request Structure - nfapi_nr_dl_config_request_t DL_req[NFAPI_CC_MAX]; - /// NFAPI UL Config Request Structure, send to L1 4 subframes before processing takes place - nfapi_ul_config_request_t UL_req[NFAPI_CC_MAX]; - /// Preallocated DL pdu list - nfapi_nr_dl_config_request_pdu_t dl_config_pdu_list[NFAPI_CC_MAX][MAX_NUM_DL_PDU]; - /// Preallocated UL pdu list - nfapi_ul_config_request_pdu_t ul_config_pdu_list[NFAPI_CC_MAX][MAX_NUM_UL_PDU]; - /// Preallocated UL pdu list for ULSCH (n+k delay) - nfapi_ul_config_request_pdu_t ul_config_pdu_list_tmp[NFAPI_CC_MAX][10][MAX_NUM_UL_PDU]; - /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests - nfapi_ul_config_request_t UL_req_tmp[NFAPI_CC_MAX][10]; - /// Preallocated HI_DCI0 pdu list - nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[NFAPI_CC_MAX][MAX_NUM_HI_DCI0_PDU]; + nfapi_nr_dl_tti_request_t DL_req[NFAPI_CC_MAX]; + /// NFAPI UL TTI Request Structure (this is from the new SCF specs) + nfapi_nr_ul_tti_request_t UL_tti_req[NFAPI_CC_MAX]; /// NFAPI HI/DCI0 Config Request Structure - nfapi_hi_dci0_request_t HI_DCI0_req[NFAPI_CC_MAX]; - /// Prealocated TX pdu list - nfapi_tx_request_pdu_t tx_request_pdu[NFAPI_CC_MAX][MAX_NUM_TX_REQUEST_PDU]; + nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX]; /// NFAPI DL PDU structure - nfapi_tx_request_t TX_req[NFAPI_CC_MAX]; + nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX]; NR_UE_list_t UE_list; /// UL handle @@ -190,6 +177,72 @@ typedef struct gNB_MAC_INST_s { time_stats_t rx_ulsch_sdu; // include rlc_data_ind /// processing time of eNB PCH scheduler time_stats_t schedule_pch; + /// CCE lists + int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE]; } gNB_MAC_INST; +typedef struct { + + +uint8_t format_indicator; //1 bit +uint16_t frequency_domain_assignment; //up to 16 bits +uint8_t time_domain_assignment; // 4 bits +uint8_t frequency_hopping_flag; //1 bit + +uint8_t ra_preamble_index; //6 bits +uint8_t ss_pbch_index; //6 bits +uint8_t prach_mask_index; //4 bits + +uint8_t vrb_to_prb_mapping; //0 or 1 bit +uint8_t mcs; //5 bits +uint8_t ndi; //1 bit +uint8_t rv; //2 bits +uint8_t harq_pid; //4 bits +uint8_t dai; //0, 2 or 4 bits +uint8_t dai1; //1 or 2 bits +uint8_t dai2; //0 or 2 bits +uint8_t tpc; //2 bits +uint8_t pucch_resource_indicator; //3 bits +uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits + +uint8_t short_messages_indicator; //2 bits +uint8_t short_messages; //8 bits +uint8_t tb_scaling; //2 bits + +uint8_t carrier_indicator; //0 or 3 bits +uint8_t bwp_indicator; //0, 1 or 2 bits +uint8_t prb_bundling_size_indicator; //0 or 1 bits +uint8_t rate_matching_indicator; //0, 1 or 2 bits +uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits +uint8_t transmission_configuration_indication; //0 or 3 bits +uint8_t srs_request; //2 bits +uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits +uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit +uint8_t dmrs_sequence_initialization; //0 or 1 bit + +uint8_t srs_resource_indicator; +uint8_t precoding_information; +uint8_t csi_request; +uint8_t ptrs_dmrs_association; +uint8_t beta_offset_indicator; //0 or 2 bits + +uint8_t slot_format_indicator_count; +uint8_t *slot_format_indicators; + +uint8_t pre_emption_indication_count; +uint16_t *pre_emption_indications; //14 bit + +uint8_t block_number_count; +uint8_t *block_numbers; + +uint8_t ul_sul_indicator; //0 or 1 bit +uint8_t antenna_ports; + +uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits +uint16_t padding; + +} dci_pdu_rel15_t; + + + #endif /*__LAYER2_NR_MAC_GNB_H__ */ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index b5a68069cc..f234e02c04 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -146,12 +146,12 @@ boolean_t pdcp_data_req( sdu_buffer_sizeP, MAX_IP_PACKET_SIZE); if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { - AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); } else { if (srb_flagP) { - AssertError (rb_idP < 3, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < 3, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); } else { - AssertError (rb_idP < LTE_maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); } } @@ -160,7 +160,7 @@ boolean_t pdcp_data_req( if (h_rc != HASH_TABLE_OK) { if (modeP != PDCP_TRANSMISSION_MODE_TRANSPARENT) { - LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %d Ignoring SDU...\n", + LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %ld Ignoring SDU...\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); ctxt_pP->configured=FALSE; @@ -190,7 +190,7 @@ boolean_t pdcp_data_req( rlc_util_print_hex_octets(PDCP, (unsigned char *)&pdcp_pdu_p->data[0], sdu_buffer_sizeP); - LOG_UI(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP); + LOG_UI(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %ld \n", srb_flagP, rb_idP); } rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)?MBMS_FLAG_NO:MBMS_FLAG_YES, rb_idP, muiP, @@ -338,7 +338,7 @@ boolean_t pdcp_data_req( stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); } - LOG_E(PDCP, "[FRAME %5u][%s][PDCP][MOD %u][RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", + LOG_E(PDCP, "[FRAME %5u][%s][PDCP][MOD %u][RB %ld] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", ctxt_pP->frame, (ctxt_pP->enb_flag) ? "eNB" : "UE", ctxt_pP->module_id, @@ -352,20 +352,29 @@ boolean_t pdcp_data_req( * to see if RLC succeeded */ LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size, - "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); + "[MSG] PDCP DL %s PDU on rb_id %ld\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); if ((pdcp_pdu_p!=NULL) && (srb_flagP == 0) && (ctxt_pP->enb_flag == 1)) { - LOG_D(PDCP, "pdcp data req on drb %d, size %d, rnti %x, node_type %d \n", - rb_idP, pdcp_pdu_size, ctxt_pP->rnti, RC.rrc[ctxt_pP->module_id]->node_type); + LOG_D(PDCP, "pdcp data req on drb %ld, size %d, rnti %x, node_type %d \n", + rb_idP, pdcp_pdu_size, ctxt_pP->rnti, RC.rrc ? RC.rrc[ctxt_pP->module_id]->node_type: -1); - if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) { + // The check on nos1 is done only for the use case of LTE stack running over 5g-nr PHY. This should be changed + // before future merge of develop with develop-nr and instead of a check of IS_SOFTMODEM_NOS1, we should use a check + // with a new execution option capturing the nr-ip-over-LTE-stack use case. + ngran_node_t node_type; + if (IS_SOFTMODEM_NOS1) + node_type = ngran_gNB; + else + node_type = RC.rrc[ctxt_pP->module_id]->node_type; + + if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(node_type)) { //RC.rrc[ctxt_pP->module_id]->node_type LOG_E(PDCP, "Can't be DU, bad node type %d \n", RC.rrc[ctxt_pP->module_id]->node_type); ret=FALSE; } else { rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p,sourceL2Id, destinationL2Id); - + ret=FALSE; switch (rlc_status) { case RLC_OP_STATUS_OK: LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); @@ -374,22 +383,18 @@ boolean_t pdcp_data_req( case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; break; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; break; case RLC_OP_STATUS_OUT_OF_RESSOURCES: LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; break; default: LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; break; } // switch case } /* end if node_type is not DU */ @@ -510,6 +515,7 @@ pdcp_data_ind( hashtable_rc_t h_rc; uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 :0; uint16_t pdcp_uid=0; + MessageDef *message_p = NULL; uint8_t *gtpu_buffer_p = NULL; uint32_t rx_hfn_for_count; @@ -517,17 +523,11 @@ pdcp_data_ind( int security_ok; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN); LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP, - "[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); -#if T_TRACER - - if (ctxt_pP->enb_flag != ENB_FLAG_NO) - T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP)); - -#endif + "[MSG] PDCP UL %s PDU on rb_id %ld\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); if (MBMS_flagP) { AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, - "RB id is too high (%u/%d) %u rnti %x!\n", + "RB id is too high (%ld/%d) %u rnti %x!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, @@ -535,7 +535,7 @@ pdcp_data_ind( if (ctxt_pP->enb_flag == ENB_FLAG_NO) { LOG_D(PDCP, "e-MBMS Data indication notification for PDCP entity from eNB %u to UE %x " - "and radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n", + "and radio bearer ID %ld rlc sdu size %d ctxt_pP->enb_flag %d\n", ctxt_pP->module_id, ctxt_pP->rnti, rb_idP, @@ -543,7 +543,7 @@ pdcp_data_ind( ctxt_pP->enb_flag); } else { LOG_D(PDCP, "Data indication notification for PDCP entity from UE %x to eNB %u " - "and radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n", + "and radio bearer ID %ld rlc sdu size %d ctxt_pP->enb_flag %d\n", ctxt_pP->rnti, ctxt_pP->module_id, rb_idP, @@ -552,12 +552,12 @@ pdcp_data_ind( } } else { rb_id = rb_idP % LTE_maxDRB; - AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%u/%d) %u UE %x!\n", + AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); - AssertError (rb_id > 0, return FALSE, "RB id is too low (%u/%d) %u UE %x!\n", + AssertError (rb_id > 0, return FALSE, "RB id is too low (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, @@ -723,14 +723,6 @@ pdcp_data_ind( pdcp_p->rx_hfn++; } - //rrc_lite_data_ind(module_id, //Modified MW - L2 Interface - MSC_LOG_TX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_NO)? MSC_PDCP_UE:MSC_PDCP_ENB, - (ctxt_pP->enb_flag == ENB_FLAG_NO)? MSC_RRC_UE:MSC_RRC_ENB, - NULL,0, - PROTOCOL_PDCP_CTXT_FMT" DATA-IND len %u", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), - sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len); rrc_data_ind(ctxt_pP, rb_id, sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len, @@ -933,7 +925,7 @@ pdcp_data_ind( if (LINK_ENB_PDCP_TO_GTPV1U) { if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) { - LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %u len %u\n", + LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %ld len %u\n", ctxt_pP->rnti, rb_id + 4, sdu_buffer_sizeP - payload_offset ); @@ -1040,6 +1032,13 @@ pdcp_data_ind( memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset); + + #if defined(ENABLE_PDCP_PAYLOAD_DEBUG) + LOG_I(PDCP, "Printing first bytes of PDCP SDU before adding it to the list: \n"); + for (int i=0; i<30; i++){ + LOG_I(PDCP, "%x", sdu_buffer_pP->data[i]); + } + #endif list_add_tail_eurecom (new_sdu_p, sdu_list_p); } @@ -1062,6 +1061,7 @@ pdcp_data_ind( Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); + Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); @@ -1166,7 +1166,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).frame, 0, RRC_DCCH_DATA_REQ (msg_p).eNB_index); - LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %ld, muiP %d, confirmP %d, mode %d\n", PROTOCOL_CTXT_ARGS(&ctxt), ITTI_MSG_NAME (msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), @@ -1175,7 +1175,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).muip, RRC_DCCH_DATA_REQ (msg_p).confirmp, RRC_DCCH_DATA_REQ (msg_p).mode); - LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); + LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %ld \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); result = pdcp_data_req (&ctxt, SRB_FLAG_YES, RRC_DCCH_DATA_REQ (msg_p).rb_id, @@ -1772,6 +1772,7 @@ pdcp_config_req_asn1 ( uint8_t *const kUPenc_pP) //----------------------------------------------------------------------------- { + switch (actionP) { case CONFIG_ACTION_ADD: DevAssert(pdcp_pP != NULL); @@ -1825,7 +1826,7 @@ pdcp_config_req_asn1 ( pdcp_pP->rx_hfn = 0; pdcp_pP->last_submitted_pdcp_rx_sn = 4095; pdcp_pP->first_missing_pdu = -1; - LOG_I(PDCP, PROTOCOL_PDCP_CTXT_FMT" Action ADD LCID %d (%s id %d) " + LOG_I(PDCP, PROTOCOL_PDCP_CTXT_FMT" Action ADD LCID %d (%s id %ld) " "configured with SN size %d bits and RLC %s\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), lc_idP, @@ -1877,7 +1878,7 @@ pdcp_config_req_asn1 ( } LOG_I(PDCP,PROTOCOL_PDCP_CTXT_FMT" Action MODIFY LCID %d " - "RB id %d reconfigured with SN size %d and RLC %s \n", + "RB id %ld reconfigured with SN size %d and RLC %s \n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), lc_idP, rb_idP, @@ -1889,7 +1890,7 @@ pdcp_config_req_asn1 ( DevAssert(pdcp_pP != NULL); //#warning "TODO pdcp_module_id_to_rnti" //pdcp_module_id_to_rnti[ctxt_pP.module_id ][dst_id] = NOT_A_RNTI; - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE LCID %d RBID %d configured\n", + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE LCID %d RBID %ld configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), lc_idP, rb_idP); @@ -1916,7 +1917,7 @@ pdcp_config_req_asn1 ( case CONFIG_ACTION_MBMS_ADD: case CONFIG_ACTION_MBMS_MODIFY: - LOG_D(PDCP," %s service_id/mch index %d, session_id/lcid %d, rbid %d configured\n", + LOG_D(PDCP," %s service_id/mch index %d, session_id/lcid %d, rbid %ld configured\n", //PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), actionP == CONFIG_ACTION_MBMS_ADD ? "CONFIG_ACTION_MBMS_ADD" : "CONFIG_ACTION_MBMS_MODIFY", mch_idP, @@ -2042,7 +2043,7 @@ rrc_pdcp_config_req ( } pdcp_p->first_missing_pdu = -1; - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d (already added) configured\n", + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %ld (already added) configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), rb_idP); break; @@ -2051,7 +2052,7 @@ rrc_pdcp_config_req ( break; case CONFIG_ACTION_REMOVE: - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE: radio bearer id %d configured\n", + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE: radio bearer id %ld configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), rb_idP); pdcp_p->next_pdcp_tx_sn = 0; @@ -2120,7 +2121,7 @@ rrc_pdcp_config_req ( pdcp_p->first_missing_pdu = -1; LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Inserting PDCP instance in collection key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), key); - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d configured\n", + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %ld configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), rb_idP); } @@ -2170,6 +2171,9 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { if(UE_NAS_USE_TUN) { int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; netlink_init_tun("ue",num_if); + //Add --nr-ip-over-lte option check for next line + if (IS_SOFTMODEM_NOS1) + nas_config(1, 1, 2, "ue"); LOG_I(PDCP, "UE pdcp will use tun interface\n"); } else if(ENB_NAS_USE_TUN) { netlink_init_tun("enb",1); @@ -2217,6 +2221,101 @@ void pdcp_module_cleanup (void) { } +void nr_ip_over_LTE_DRB_preconfiguration(void){ + + // Addition for the use-case of 4G stack on top of 5G-NR. + // We need to configure pdcp and rlc instances without having an actual + // UE RRC Connection. In order to be able to test the NR PHY with some injected traffic + // on top of the LTE stack. + protocol_ctxt_t ctxt; + LTE_DRB_ToAddModList_t* DRB_configList=NULL; + DRB_configList = CALLOC(1, sizeof(LTE_DRB_ToAddModList_t)); + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + + struct LTE_DRB_ToAddMod *DRB_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; + long *logicalchannelgroup_drb; + + + //Static preconfiguration of DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); + + DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(DRB_config->eps_BearerIdentity) = 1; //ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation + // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + // 1 + drb_identiy_index; + DRB_config->drb_Identity = 1; + DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); + DRB_config->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + DRB_config->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; + // PDCP + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; + + DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); + DRB_config->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority= 4; + + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + *logicalchannelgroup_drb = 1;//(i+1) % 3; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + ASN_SEQUENCE_ADD(&DRB_configList->list,DRB_config); + + if (ENB_NAS_USE_TUN){ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0); + } + else{ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + } + + rrc_pdcp_config_asn1_req(&ctxt, + (LTE_SRB_ToAddModList_t *) NULL, + DRB_configList, + (LTE_DRB_ToReleaseList_t *) NULL, + 0xff, NULL, NULL, NULL + , (LTE_PMCH_InfoList_r9_t *) NULL, + &DRB_config->drb_Identity); + + rrc_rlc_config_asn1_req(&ctxt, + (LTE_SRB_ToAddModList_t*)NULL, + DRB_configList, + (LTE_DRB_ToReleaseList_t*)NULL + //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL + , 0, 0 + //#endif + ); +} //----------------------------------------------------------------------------- void pdcp_layer_init(void) //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 8d741c1bb5..1d4c612743 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -87,11 +87,13 @@ extern pthread_mutex_t pdcp_mutex; extern pthread_cond_t pdcp_cond; extern int pdcp_instance_cnt; -#define PROTOCOL_PDCP_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] " +#define PROTOCOL_PDCP_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld] " #define PROTOCOL_PDCP_CTXT_ARGS(CTXT_Pp, pDCP_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (pDCP_Pp->is_srb) ? "SRB" : "DRB",\ pDCP_Pp->rb_id +//#define ENABLE_PDCP_PAYLOAD_DEBUG 1 + int init_pdcp_thread(void); void cleanup_pdcp_thread(void); @@ -397,6 +399,7 @@ void pdcp_run ( const protocol_ctxt_t *const ctxt_pP); uint64_t pdcp_module_init (uint64_t pdcp_optmask); void pdcp_module_cleanup (void); +void nr_ip_over_LTE_DRB_preconfiguration (void); void pdcp_layer_init (void); void pdcp_layer_cleanup (void); #define PDCP2NW_DRIVER_FIFO 21 diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 3d8c42bc8c..9e873379b1 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -98,7 +98,7 @@ extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) { LOG_I(PDCP,"%s: \nPC5S message, header traffic_type: %d)\n", title, sl_pc5s_msg->pc5s_header.traffic_type); - LOG_I(PDCP,"PC5S message, header rb_id: %d)\n", sl_pc5s_msg->pc5s_header.rb_id); + LOG_I(PDCP,"PC5S message, header rb_id: %ld)\n", sl_pc5s_msg->pc5s_header.rb_id); LOG_I(PDCP,"PC5S message, header data_size: %d)\n", sl_pc5s_msg->pc5s_header.data_size); LOG_I(PDCP,"PC5S message, header inst: %d)\n", sl_pc5s_msg->pc5s_header.inst); LOG_I(PDCP,"PC5-S message, sourceL2Id: 0x%08x\n)\n", sl_pc5s_msg->pc5s_header.sourceL2Id); @@ -111,7 +111,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { int ret=0; while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) { - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id; int sizeToWrite= sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size; @@ -135,6 +135,13 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { } // PDCP_USE_NETLINK AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); + + #if defined(ENABLE_PDCP_PAYLOAD_DEBUG) + LOG_I(PDCP, "Printing first bytes of PDCP SDU before removing it from the list: \n"); + for (int i=0; i<30; i++){ + LOG_I(PDCP, "%x", sdu_p->data[i]); + } + #endif list_remove_head (&pdcp_sdu_list); free_mem_block (sdu_p, __func__); pdcp_nb_sdu_sent ++; @@ -166,7 +173,7 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0]; ctxt.enb_flag=ENB_FLAG_YES; ctxt.module_id=0; - key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_YES); + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); } @@ -174,33 +181,19 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { ctxt.module_id, ctxt.rnti, ctxt.enb_flag); if (h_rc == HASH_TABLE_OK) { - LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n", ctxt.frame, ctxt.instance, len, rab_id); - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %ld]\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id); - MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt.instance, rab_id, rab_id, len); pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf, PDCP_TRANSMISSION_MODE_DATA , NULL, NULL ); } else { - MSC_LOG_RX_DISCARDED_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt.instance, rab_id, rab_id, len); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %ld] TUN NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id, key); } @@ -246,7 +239,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { pdcp_read_state_g = 1; //get memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); - LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n", + LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %ld data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n", pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size,pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id ); } else { LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n", @@ -262,7 +255,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; - LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id, + LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %ld, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id); if (ctxt.enb_flag) { @@ -276,24 +269,14 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc == HASH_TABLE_OK) { - LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", + LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %ld for rnti: %d \n", ctxt.frame, pdcp_read_header_g.inst, len, nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), - pdcp_read_header_g.rb_id); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n", + pdcp_read_header_g.rb_id, + ctxt.rnti); + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %ld]\n", ctxt_cpy.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -312,7 +295,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ,NULL, NULL ); } else { - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %ld] NON INSTANCIATED INSTANCE, DROPPED\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -327,7 +310,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -369,27 +352,27 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ctxt.module_id, ctxt.rnti, ctxt.enb_flag); key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_D(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } else { rab_id = rab_id % LTE_maxDRB; - LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%ld, SRB_FLAG=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_D(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } if (h_rc == HASH_TABLE_OK) { rab_id = pdcp_p->rb_id; - LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %ld \n", ctxt.frame, pdcp_read_header_g.inst, len, nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), pdcp_read_header_g.rb_id); - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %ld]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -397,17 +380,6 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ctxt.module_id, ctxt.rnti, rab_id); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); pdcp_data_req( &ctxt, SRB_FLAG_NO, @@ -433,7 +405,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx rab_id, pdcp_read_header_g.data_size); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %ld] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -445,7 +417,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx } /* h_rc != HASH_TABLE_OK */ } else {/* else of rab_id != 0 */ LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -453,16 +425,6 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ctxt.module_id, ctxt.rnti, DEFAULT_RAB_ID); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL,0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - DEFAULT_RAB_ID, - pdcp_read_header_g.data_size); pdcp_data_req ( &ctxt, SRB_FLAG_NO, @@ -547,7 +509,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; - LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id); + LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %ld\n", pc5s_header->rb_id); if (ctxt_cpy.enb_flag) { ctxt.module_id = 0; @@ -567,26 +529,26 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) ctxt.module_id, ctxt.rnti, ctxt.enb_flag); key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_D(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } else { rab_id = rab_id % LTE_maxDRB; - LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%ld, SRB_FLAG=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_I(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } if (h_rc == HASH_TABLE_OK) { rab_id = pdcp_p->rb_id; - LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n", ctxt.frame, pc5s_header->inst, bytes_received, pc5s_header->rb_id); - LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %ld]\n", ctxt.frame, pc5s_header->inst, pc5s_header->rb_id, @@ -630,7 +592,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) rab_id, pc5s_header->data_size); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %ld] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, pc5s_header->inst, pc5s_header->rb_id, @@ -642,7 +604,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) } } else { /* else of if (rab_id == 0) */ LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pc5s_header->inst, pc5s_header->rb_id, @@ -698,28 +660,6 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { return 0; } - -void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t *const ctxt_pP) { - module_id_t dst_id; // dst for otg - protocol_ctxt_t ctxt; - - // we need to add conditions to avoid transmitting data when the UE is not RRC connected. - if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic - PROTOCOL_CTXT_SET_BY_MODULE_ID( - &ctxt, - ctxt_pP->module_id, - ctxt_pP->enb_flag, - NOT_A_RNTI, - ctxt_pP->frame, - ctxt_pP->subframe, - ctxt_pP->module_id); - - for (dst_id = 0; dst_idpdcp_read_header, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); LOG_I(PDCP, "[NETLINK_THREAD] RX pdcp_data_req_header_t inst %u, " - "rb_id %u data_size %d\n", + "rb_id %ld data_size %d\n", new_data_p->pdcp_read_header.inst, new_data_p->pdcp_read_header.rb_id, new_data_p->pdcp_read_header.data_size); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index a18713fbb6..8f9ee0af18 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -128,7 +128,7 @@ pdcp_apply_security( /* SRBs */ uint8_t *mac_i; - LOG_D(PDCP, "[OSA][RB %d] %s Applying control-plane security %d \n", + LOG_D(PDCP, "[OSA][RB %ld] %s Applying control-plane security %d \n", rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE", pdcp_pP->integrityProtAlgorithm); encrypt_params.message = pdcp_pdu_buffer; @@ -145,7 +145,7 @@ pdcp_apply_security( encrypt_params.key = pdcp_pP->kRRCenc; // + 128 // bit key } else { - LOG_D(PDCP, "[OSA][RB %d] %s Applying user-plane security\n", + LOG_D(PDCP, "[OSA][RB %ld] %s Applying user-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE"); encrypt_params.key = pdcp_pP->kUPenc;// + 128; @@ -200,11 +200,11 @@ pdcp_validate_security( decrypt_params.key_length = 16; if (srb_flagP) { - LOG_D(PDCP, "[OSA][RB %d] %s Validating control-plane security\n", + LOG_D(PDCP, "[OSA][RB %ld] %s Validating control-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kRRCenc;// + 128; } else { - LOG_D(PDCP, "[OSA][RB %d] %s Validating user-plane security\n", + LOG_D(PDCP, "[OSA][RB %ld] %s Validating user-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kUPenc;// + 128; } @@ -228,7 +228,7 @@ pdcp_validate_security( " Security: failed MAC-I Algo %X UE %"PRIx16" ", pdcp_pP->integrityProtAlgorithm, ctxt_pP->rnti); - LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I (key %llx) of incoming PDU\n", + LOG_E(PDCP, "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); return -1; diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c index 02e1b63129..a11c029bd3 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c @@ -543,7 +543,7 @@ int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Proto // if (xid == 1) // pdcp_data_ind_wifi((const protocol_ctxt_t*) ctxt_pP, (const srb_flag_t) srb_flagP, (const MBMS_flag_t) flag_MBMS, (const rb_id_t) rb_idP, pdcp_pdu_size, pdcp_pdu_p); // else if (xid == 0) // FIXME: USE a preprocessed definition - LOG_D(PROTO_AGENT, "[inst %d] Received PDCP PDU with size %d for UE RNTI %x RB %d, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP); + LOG_D(PROTO_AGENT, "[inst %d] Received PDCP PDU with size %d for UE RNTI %x RB %ld, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP); result = pdcp_data_ind(&ctxt_pP, srb_flagP, flag_MBMS, diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index ef40b186e0..865a815359 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -672,7 +672,7 @@ rlc_am_mac_data_request ( if ( LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -771,7 +771,7 @@ rlc_am_mac_data_request ( if ( LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "PDU type : RLC AM DATA REQ: STATUS PDU\n\n"); message_string_size += sprintf(&message_string[message_string_size], "Header :\n"); @@ -874,7 +874,7 @@ rlc_am_mac_data_indication ( } if ( LOG_DEBUGFLAG(DEBUG_RLC)) { - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -971,7 +971,7 @@ rlc_am_mac_data_indication ( if ( LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", ((struct mac_tb_ind *) (tb_p->data))->size); message_string_size += sprintf(&message_string[message_string_size], "PDU type : RLC AM DATA IND: STATUS PDU\n\n"); message_string_size += sprintf(&message_string[message_string_size], "Header :\n"); @@ -1039,7 +1039,7 @@ rlc_am_data_req ( mui); if (LOG_DEBUGFLAG(DEBUG_RLC)) { - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", data_size); message_string_size += sprintf(&message_string[message_string_size], "MUI : %u\n", mui); message_string_size += sprintf(&message_string[message_string_size], "CONF : %u\n", ((struct rlc_am_data_req *) (sdu_pP->data))->conf); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h index c6a5ca7213..f2cb456e8c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h @@ -60,12 +60,12 @@ //# include "rlc_am_test.h" -#define PROTOCOL_RLC_AM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u]" +#define PROTOCOL_RLC_AM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld]" #define PROTOCOL_RLC_AM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\ rLC_Pp->rb_id -#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]" +#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %" PRIx16 " %s %02ld]" #define PROTOCOL_RLC_AM_MSC_ARGS(CTXT_Pp, rLC_Pp) \ CTXT_Pp->rnti,\ (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index 369c7fd0da..793d0057ac 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -111,7 +111,7 @@ rlc_am_send_sdu ( char message_string[7000]; size_t message_string_size = 0; int octet_index, index; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_pP->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", rlc_pP->rb_id); message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", rlc_pP->output_sdu_size_to_write); message_string_size += sprintf(&message_string[message_string_size], "\nPayload : \n"); message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n"); diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h index a5bd0b9ef5..1ea9988707 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h @@ -42,7 +42,7 @@ # include "mem_block.h" # include "rlc_tm_init.h" -#define PROTOCOL_RLC_TM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u]" +#define PROTOCOL_RLC_TM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld]" #define PROTOCOL_RLC_TM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (rLC_Pp->is_data_plane) ? "DRB TM" : "SRB TM",\ rLC_Pp->rb_id diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c index 78d7cc515f..22e6f4d78d 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c @@ -42,7 +42,7 @@ void config_req_rlc_tm ( if (h_rc == HASH_TABLE_OK) { rlc_p = &rlc_union_p->rlc.tm; - LOG_D(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ (is_uplink_downlink=%d) RB %u\n", + LOG_D(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ (is_uplink_downlink=%d) RB %ld\n", PROTOCOL_RLC_TM_CTXT_ARGS(ctxt_pP, rlc_p), config_tmP->is_uplink_downlink, rb_idP); @@ -52,7 +52,7 @@ void config_req_rlc_tm ( rlc_tm_set_debug_infos(ctxt_pP, rlc_p, srb_flagP, rb_idP, chan_idP); rlc_tm_configure(ctxt_pP, rlc_p, config_tmP->is_uplink_downlink); } else { - LOG_E(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ RB %u RLC NOT FOUND\n", + LOG_E(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ RB %ld RLC NOT FOUND\n", PROTOCOL_RLC_TM_CTXT_ARGS(ctxt_pP, rlc_p), rb_idP); } diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c index 66a544f962..c7dc11f51d 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c @@ -279,7 +279,7 @@ rlc_um_rx (const protocol_ctxt_t *const ctxt_pP, void *argP, struct mac_data_ind if (LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -525,7 +525,7 @@ rlc_um_mac_data_request (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP,cons if(LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -631,7 +631,7 @@ rlc_um_data_req (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP, mem_block_t if (LOG_DEBUGFLAG(DEBUG_RLC) ) { data_offset = sizeof (struct rlc_um_data_req_alloc); data_size = ((struct rlc_um_tx_sdu_management *)(sdu_pP->data))->sdu_size; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", data_size); message_string_size += sprintf(&message_string[message_string_size], "\nPayload : \n"); message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n"); diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h index fc6e449acf..8000196b32 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h @@ -50,13 +50,13 @@ # include "rlc_um_segment.h" # include "rlc_um_test.h" -#define PROTOCOL_RLC_UM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] %s()" +#define PROTOCOL_RLC_UM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld] %s()" #define PROTOCOL_RLC_UM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (rLC_Pp->is_data_plane) ? "DRB UM" : "SRB UM",\ rLC_Pp->rb_id,\ __FUNCTION__ -#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]" +#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %" PRIx16 " %s %02ld]" #define PROTOCOL_RLC_UM_MSC_ARGS(CTXT_Pp, rLC_Pp) \ CTXT_Pp->rnti,\ (rLC_Pp->is_data_plane) ? "DRB UM" : "SRB UM",\ diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c index 77194f3a9e..940740943e 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c @@ -50,7 +50,7 @@ void config_req_rlc_um ( if (h_rc == HASH_TABLE_OK) { rlc_p = &rlc_union_p->rlc.um; - LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%d sn_field_length=%d is_mXch=%d RB %u\n", + LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%d sn_field_length=%d is_mXch=%d RB %ld\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), config_um_pP->timer_reordering, config_um_pP->sn_field_length, @@ -69,7 +69,7 @@ void config_req_rlc_um ( config_um_pP->is_mXch); } } else { - LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ RB %u RLC UM NOT FOUND\n", + LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ RB %ld RLC UM NOT FOUND\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rb_idP); } @@ -143,14 +143,14 @@ void config_req_rlc_um_asn1 ( // rb_idP, // srb_flagP); if(h_rc != HASH_TABLE_OK) { - LOG_E(RLC, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %u, srb flag %u\n", + LOG_E(RLC, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %ld, srb flag %u\n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); return; } rlc_p = &rlc_union_p->rlc.um; //----------------------------------------------------------------------------- - LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%dms sn_field_length= RB %u \n", + LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%dms sn_field_length= RB %ld \n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), (dl_rlc_pP && dl_rlc_pP->t_Reordering<31)?t_Reordering_tab[dl_rlc_pP->t_Reordering]:-1, rb_idP); @@ -170,7 +170,7 @@ void config_req_rlc_um_asn1 ( break; default: - LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID UL sn_FieldLength %ld, RLC NOT CONFIGURED\n", + LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID UL sn_FieldLength %ld, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, ul_rlc_pP->sn_FieldLength); @@ -198,7 +198,7 @@ void config_req_rlc_um_asn1 ( break; default: - LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID DL sn_FieldLength %ld, RLC NOT CONFIGURED\n", + LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID DL sn_FieldLength %ld, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, dl_rlc_pP->sn_FieldLength); @@ -217,7 +217,7 @@ void config_req_rlc_um_asn1 ( if (dl_rlc_pP->t_Reordering<32) { t_Reordering = t_Reordering_tab[dl_rlc_pP->t_Reordering]; } else { - LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID T_Reordering %ld, RLC NOT CONFIGURED\n", + LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID T_Reordering %ld, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, dl_rlc_pP->t_Reordering); @@ -382,7 +382,7 @@ void rlc_um_configure( rlc_pP->rx_um_window_size = RLC_UM_WINDOW_SIZE_SN_5_BITS; rlc_pP->rx_header_min_length_in_bytes = 1; } else if (rx_sn_field_lengthP != 0) { - LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", + LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->rb_id, rx_sn_field_lengthP); @@ -400,7 +400,7 @@ void rlc_um_configure( rlc_pP->tx_um_window_size = RLC_UM_WINDOW_SIZE_SN_5_BITS; rlc_pP->tx_header_min_length_in_bytes = 1; } else if (tx_sn_field_lengthP != 0) { - LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", + LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->rb_id, tx_sn_field_lengthP); @@ -428,7 +428,7 @@ void rlc_um_set_debug_infos( const srb_flag_t srb_flagP, const rb_id_t rb_idP, const logical_chan_id_t chan_idP) { - LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [SET DEBUG INFOS] rb_id %d srb_flag %d\n", + LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [SET DEBUG INFOS] rb_id %ld srb_flag %d\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), rb_idP, srb_flagP); diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c index f37626ae4c..c8faa08358 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c @@ -723,7 +723,6 @@ void rlc_um_check_timer_dar_time_out( signed int in_window; rlc_usn_t old_vr_ur; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_UM_CHECK_TIMER_DAR_TIME_OUT,VCD_FUNCTION_IN); if ((rlc_pP->t_reordering.running)) { @@ -1130,12 +1129,12 @@ rlc_um_receive_process_dar ( if (in_window < 0) { in_window = in_window + rlc_pP->rx_sn_modulo; } - rlc_um_try_reassembly(ctxt_pP, rlc_pP, rlc_pP->vr_ur, in_window); } if (rlc_um_in_reordering_window(ctxt_pP, rlc_pP, rlc_pP->vr_ur) < 0) { + //LOG_I(RLC, "[rlc_um_receive_process_dar] Problematic case 4 \n"); #if TRACE_RLC_UM_DAR LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" VR(UR) %d OUTSIDE REORDERING WINDOW SET TO VR(UH) – UM_Window_Size = %d\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP), @@ -1158,9 +1157,8 @@ rlc_um_receive_process_dar ( do { rlc_pP->vr_ur = (rlc_pP->vr_ur+1) % rlc_pP->rx_sn_modulo; } while (rlc_um_get_pdu_from_dar_buffer(ctxt_pP, rlc_pP, rlc_pP->vr_ur) && (rlc_pP->vr_ur != rlc_pP->vr_uh)); - rlc_um_try_reassembly(ctxt_pP, rlc_pP, sn, rlc_pP->vr_ur); - } + } // -if t-Reordering is running: // -if VR(UX) <= VR(UR); or diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c index b6ab367bc1..90e006cd17 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c @@ -50,7 +50,7 @@ rlc_um_display_rx_window( LOG_T(RLC, "\n"); sprintf(time_out_str, "%010d", rlc_pP->t_reordering.ms_duration); time_out_str[10] = 0; - LOG_T(RLC, "| RLC UM RB %02d VR(UR)=%03d VR(UX)=%03d VR(UH)=%03d t-Reordering: %s %s %s |", + LOG_T(RLC, "| RLC UM RB %02ld VR(UR)=%03d VR(UX)=%03d VR(UH)=%03d t-Reordering: %s %s %s |", rlc_pP->rb_id, rlc_pP->vr_ur, rlc_pP->vr_ux, rlc_pP->vr_uh, (rlc_pP->t_reordering.running)?" ON":"OFF", (rlc_pP->t_reordering.running)?"Time-out frameP:":" ", diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 1563a01de3..2fb844f05a 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -137,7 +137,7 @@ rlc_op_status_t rlc_stat_req ( //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } @@ -332,7 +332,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t log_ch_id = 0; #ifdef DEBUG_RLC_DATA_REQ - LOG_D(RLC,PROTOCOL_CTXT_FMT"rlc_data_req: rb_id %u (MAX %d), muip %d, confirmP %d, sdu_sizeP %d, sdu_pP %p\n", + LOG_D(RLC,PROTOCOL_CTXT_FMT"rlc_data_req: rb_id %ld (MAX %d), muip %d, confirmP %d, sdu_sizeP %d, sdu_pP %p\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP, NB_RAB_MAX, @@ -351,13 +351,13 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, if (MBMS_flagP) { //AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX); if(rb_idP >= NB_RB_MBMS_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MBMS_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } } else { //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } } @@ -387,14 +387,14 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); } else if (sourceL2Id && destinationL2Id) { - LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, + LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%ld, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); //Thinh's line originally uncommented //key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP); //key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, *sourceL2Id, *destinationL2Id, srb_flagP); } else { - LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, + LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%ld, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); } @@ -411,7 +411,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, } if (MBMS_flagP == 0) { - LOG_D(RLC, PROTOCOL_CTXT_FMT"[RB %u] Display of rlc_data_req:\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[RB %ld] Display of rlc_data_req:\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); #if defined(TRACE_RLC_PAYLOAD) @@ -424,7 +424,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, switch (rlc_mode) { case RLC_MODE_NONE: free_mem_block(sdu_pP, __func__); - LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %u\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %ld\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT); @@ -558,7 +558,7 @@ void rlc_data_ind ( const sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) { //----------------------------------------------------------------------------- - LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %ld] Display of rlc_data_ind: size %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -601,7 +601,8 @@ void rlc_data_conf (const protocol_ctxt_t *const ctxt_pP, } //----------------------------------------------------------------------------- int -rlc_module_init (void) { +rlc_module_init (int enb_flag) { /* enb_flag is unused, but needed for binary + * compatibility with rlc_v2 */ //----------------------------------------------------------------------------- int k; module_id_t module_id1; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index dddffed241..dfdf527123 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -197,7 +197,7 @@ rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_ #define rlc_mbms_ue_get_lcid_by_rb_id(uE_mOD,rB_iD) rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] #define rlc_mbms_ue_set_lcid_by_rb_id(uE_mOD,rB_iD,lOG_cH_iD) do { \ - AssertFatal(rB_iDlist.count; cnt++) { rb_id = srb2add_listP->list.array[cnt]->srb_Identity; lc_id = rb_id; - LOG_D(RLC, "Adding SRB %ld, rb_id %d\n",srb2add_listP->list.array[cnt]->srb_Identity,rb_id); + LOG_D(RLC, "Adding SRB %ld, rb_id %ld\n",srb2add_listP->list.array[cnt]->srb_Identity,rb_id); srb_toaddmod_p = srb2add_listP->list.array[cnt]; if (srb_toaddmod_p->rlc_Config) { @@ -102,7 +102,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am, rb_id, lc_id); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -122,7 +122,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP rb_id, lc_id,0, 0 ); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -142,7 +142,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP rb_id, lc_id,0, 0 ); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -162,7 +162,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP rb_id, lc_id,0, 0 ); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -196,7 +196,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am, rb_id,lc_id); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -213,7 +213,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP NULL, // TO DO DEFAULT CONFIG rb_id, lc_id); } else { - LOG_D(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -379,7 +379,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP } } - LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %ld SESSION ID %u SERVICE ID %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id, rb_id, @@ -502,7 +502,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } @@ -524,7 +524,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( break; default: - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] RLC mode is unknown!\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld] RLC mode is unknown!\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP); @@ -539,20 +539,20 @@ rlc_op_status_t rrc_rlc_remove_rlc ( if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { h_lcid_rc = hashtable_remove(rlc_coll_p, key_lcid); h_rc = hashtable_remove(rlc_coll_p, key); - LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASED %s\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %ld LCID %d] RELEASED %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, lcid, (srb_flagP) ? "SRB" : "DRB"); } else if ((h_rc == HASH_TABLE_KEY_NOT_EXISTS) || (h_lcid_rc == HASH_TABLE_KEY_NOT_EXISTS)) { - LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASE : RLC NOT FOUND %s, by RB-ID=%d, by LC-ID=%d\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %ld LCID %d] RELEASE : RLC NOT FOUND %s, by RB-ID=%d, by LC-ID=%d\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, lcid, (srb_flagP) ? "SRB" : "DRB", h_rc, h_lcid_rc); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASE : INTERNAL ERROR %s\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld LCID %d] RELEASE : INTERNAL ERROR %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, lcid, @@ -585,7 +585,7 @@ rlc_union_t *rrc_rlc_add_rlc ( //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); //AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return NULL; } @@ -624,7 +624,7 @@ rlc_union_t *rrc_rlc_add_rlc ( h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p); if (h_rc == HASH_TABLE_OK) { - LOG_W(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , already exist %s\n", + LOG_W(RLC, PROTOCOL_CTXT_FMT"[%s %ld] rrc_rlc_add_rlc , already exist %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -649,7 +649,7 @@ rlc_union_t *rrc_rlc_add_rlc ( mbms_id_p->service_id, mbms_id_p->session_id); } else { - LOG_I(RLC, PROTOCOL_CTXT_FMT" [%s %u] rrc_rlc_add_rlc %s\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT" [%s %ld] rrc_rlc_add_rlc %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -659,7 +659,7 @@ rlc_union_t *rrc_rlc_add_rlc ( rlc_union_p->mode = rlc_modeP; return rlc_union_p; } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc FAILED %s (add by RB_id=%d; add by LC_id=%d)\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld] rrc_rlc_add_rlc FAILED %s (add by RB_id=%d; add by LC_id=%d)\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -670,7 +670,7 @@ rlc_union_t *rrc_rlc_add_rlc ( return NULL; } } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , INTERNAL ERROR %s\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld] rrc_rlc_add_rlc , INTERNAL ERROR %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -689,13 +689,13 @@ rlc_op_status_t rrc_rlc_config_req ( const rlc_info_t rlc_infoP) { //----------------------------------------------------------------------------- //rlc_op_status_t status; - LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG_REQ for RAB %u\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG_REQ for RAB %ld\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } @@ -709,7 +709,7 @@ rlc_op_status_t rrc_rlc_config_req ( case CONFIG_ACTION_MODIFY: switch (rlc_infoP.rlc_mode) { case RLC_MODE_AM: - LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB AM\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %ld] MODIFY RB AM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_am( @@ -720,7 +720,7 @@ rlc_op_status_t rrc_rlc_config_req ( break; case RLC_MODE_UM: - LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB UM\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %ld] MODIFY RB UM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_um( @@ -731,7 +731,7 @@ rlc_op_status_t rrc_rlc_config_req ( break; case RLC_MODE_TM: - LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB TM\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %ld] MODIFY RB TM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_tm( diff --git a/openair2/LAYER2/nr_rlc/Makefile b/openair2/LAYER2/nr_rlc/Makefile new file mode 100644 index 0000000000..071930c4f4 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/Makefile @@ -0,0 +1,15 @@ +CC=gcc +CFLAGS=-Wall -g -Itests + +OBJS=nr_rlc_entity.o nr_rlc_entity_am.o nr_rlc_entity_um.o \ + nr_rlc_entity_tm.o nr_rlc_sdu.o nr_rlc_pdu.o test.o +PROG=test + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f test *.o diff --git a/openair2/LAYER2/nr_rlc/TODO b/openair2/LAYER2/nr_rlc/TODO new file mode 100644 index 0000000000..4e2d3147c9 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/TODO @@ -0,0 +1,10 @@ +RLC AM: + + - status reporting (38.322 5.3.4): implement this (not done because not + clearly understood): + + "delay triggering the STATUS report until x < RX_Highest_Status + or x >= RX_Next + AM_Window_Size." + + - send indication of successful delivery as soon as possible. Today we + signal successful delivery in order. Probably not a big issue though. diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.c b/openair2/LAYER2/nr_rlc/asn1_utils.c new file mode 100644 index 0000000000..46f7d90da5 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/asn1_utils.c @@ -0,0 +1,129 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "rlc.h" + +int decode_t_reordering(int v) +{ + static int tab[32] = { + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, + 90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 1600 + }; + + if (v < 0 || v > 31) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_t_status_prohibit(int v) +{ + static int tab[62] = { + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, + 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, + 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, + 245, 250, 300, 350, 400, 450, 500, 800, 1000, 1200, 1600, 2000, 2400 + }; + + if (v < 0 || v > 61) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_t_poll_retransmit(int v) +{ + static int tab[59] = { + 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, + 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, + 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, + 250, 300, 350, 400, 450, 500, 800, 1000, 2000, 4000 + }; + + if (v < 0 || v > 58) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_poll_pdu(int v) +{ + static int tab[8] = { + 4, 8, 16, 32, 64, 128, 256, -1 /* -1 means infinity */ + }; + + if (v < 0 || v > 7) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_poll_byte(int v) +{ + static int tab[15] = { + 25, 50, 75, 100, 125, 250, 375, 500, 750, 1000, 1250, 1500, 2000, 3000, + -1 /* -1 means infinity */ + }; + + if (v < 0 || v > 14) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (tab[v] == -1) return -1; + return tab[v] * 1024; +} + +int decode_max_retx_threshold(int v) +{ + static int tab[8] = { + 1, 2, 3, 4, 6, 8, 16, 32 + }; + + if (v < 0 || v > 7) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_sn_field_length(int v) +{ + static int tab[2] = { + 5, 10 + }; + + if (v < 0 || v > 1) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.h b/openair2/LAYER2/nr_rlc/asn1_utils.h new file mode 100644 index 0000000000..61394c9c69 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/asn1_utils.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _ASN1_UTILS_H_ +#define _ASN1_UTILS_H_ + +int decode_t_reordering(int v); +int decode_t_status_prohibit(int v); +int decode_t_poll_retransmit(int v); +int decode_poll_pdu(int v); +int decode_poll_byte(int v); +int decode_max_retx_threshold(int v); +int decode_sn_field_length(int v); + +#endif /* _ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c new file mode 100644 index 0000000000..fefe2fc77d --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -0,0 +1,174 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity.h" + +#include + +#include "nr_rlc_entity_am.h" +#include "nr_rlc_entity_um.h" +#include "nr_rlc_entity_tm.h" + +#include "LOG/log.h" + +nr_rlc_entity_t *new_nr_rlc_entity_am( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + struct nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, + struct nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length) +{ + nr_rlc_entity_am_t *ret; + + ret = calloc(1, sizeof(nr_rlc_entity_am_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ret->tx_maxsize = tx_maxsize; + ret->rx_maxsize = rx_maxsize; + + ret->t_poll_retransmit = t_poll_retransmit; + ret->t_reassembly = t_reassembly; + ret->t_status_prohibit = t_status_prohibit; + ret->poll_pdu = poll_pdu; + ret->poll_byte = poll_byte; + ret->max_retx_threshold = max_retx_threshold; + ret->sn_field_length = sn_field_length; + + if (!(sn_field_length == 12 || sn_field_length == 18)) { + LOG_E(RLC, "%s:%d:%s: wrong SN field_lenght (%d), must be 12 or 18\n", + __FILE__, __LINE__, __FUNCTION__, sn_field_length); + exit(1); + } + ret->sn_modulus = 1 << ret->sn_field_length; + ret->window_size = ret->sn_modulus / 2; + + ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_am_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; + ret->common.set_time = nr_rlc_entity_am_set_time; + ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_am_reestablishment; + ret->common.delete = nr_rlc_entity_am_delete; + + ret->common.deliver_sdu = deliver_sdu; + ret->common.deliver_sdu_data = deliver_sdu_data; + ret->common.sdu_successful_delivery = sdu_successful_delivery; + ret->common.sdu_successful_delivery_data = sdu_successful_delivery_data; + ret->common.max_retx_reached = max_retx_reached; + ret->common.max_retx_reached_data = max_retx_reached_data; + + return (nr_rlc_entity_t *)ret; +} + +nr_rlc_entity_t *new_nr_rlc_entity_um( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length) +{ + nr_rlc_entity_um_t *ret; + + ret = calloc(1, sizeof(nr_rlc_entity_um_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ret->tx_maxsize = tx_maxsize; + ret->rx_maxsize = rx_maxsize; + + ret->t_reassembly = t_reassembly; + ret->sn_field_length = sn_field_length; + + if (!(sn_field_length == 6 || sn_field_length == 12)) { + LOG_E(RLC, "%s:%d:%s: wrong SN field_lenght (%d), must be 6 or 12\n", + __FILE__, __LINE__, __FUNCTION__, sn_field_length); + exit(1); + } + ret->sn_modulus = 1 << ret->sn_field_length; + ret->window_size = ret->sn_modulus / 2; + + ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_um_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; + ret->common.set_time = nr_rlc_entity_um_set_time; + ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_um_reestablishment; + ret->common.delete = nr_rlc_entity_um_delete; + + ret->common.deliver_sdu = deliver_sdu; + ret->common.deliver_sdu_data = deliver_sdu_data; + + return (nr_rlc_entity_t *)ret; +} + +nr_rlc_entity_t *new_nr_rlc_entity_tm( + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data) +{ + nr_rlc_entity_tm_t *ret; + + ret = calloc(1, sizeof(nr_rlc_entity_tm_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ret->tx_maxsize = tx_maxsize; + + ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; + ret->common.set_time = nr_rlc_entity_tm_set_time; + ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; + ret->common.delete = nr_rlc_entity_tm_delete; + + ret->common.deliver_sdu = deliver_sdu; + ret->common.deliver_sdu_data = deliver_sdu_data; + + return (nr_rlc_entity_t *)ret; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h new file mode 100644 index 0000000000..5b12a90cfd --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -0,0 +1,104 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_H_ +#define _NR_RLC_ENTITY_H_ + +#include + +#define NR_SDU_MAX 16000 /* max NR PDCP SDU size is 9000, let's take more */ + +typedef struct { + int status_size; + int tx_size; + int retx_size; +} nr_rlc_entity_buffer_status_t; + +typedef struct nr_rlc_entity_t { + /* functions provided by the RLC module */ + void (*recv_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); + nr_rlc_entity_buffer_status_t (*buffer_status)( + struct nr_rlc_entity_t *entity, int maxsize); + int (*generate_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); + + void (*recv_sdu)(struct nr_rlc_entity_t *entity, char *buffer, int size, + int sdu_id); + + void (*set_time)(struct nr_rlc_entity_t *entity, uint64_t now); + + void (*discard_sdu)(struct nr_rlc_entity_t *entity, int sdu_id); + + void (*reestablishment)(struct nr_rlc_entity_t *entity); + + void (*delete)(struct nr_rlc_entity_t *entity); + + /* callbacks provided to the RLC module */ + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size); + void *deliver_sdu_data; + + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + struct nr_rlc_entity_t *entity, + int sdu_id); + void *sdu_successful_delivery_data; + + void (*max_retx_reached)(void *max_retx_reached_data, + struct nr_rlc_entity_t *entity); + void *max_retx_reached_data; +} nr_rlc_entity_t; + +nr_rlc_entity_t *new_nr_rlc_entity_am( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + struct nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, + struct nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length); + +nr_rlc_entity_t *new_nr_rlc_entity_um( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length); + +nr_rlc_entity_t *new_nr_rlc_entity_tm( + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data); + +#endif /* _NR_RLC_ENTITY_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c new file mode 100644 index 0000000000..8f3d49d8c2 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -0,0 +1,1844 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity_am.h" + +#include +#include + +#include "nr_rlc_pdu.h" + +#include "LOG/log.h" + +/*************************************************************************/ +/* PDU RX functions */ +/*************************************************************************/ + +static int modulus_rx(nr_rlc_entity_am_t *entity, int a) +{ + /* as per 38.322 7.1, modulus base is rx_next */ + int r = a - entity->rx_next; + if (r < 0) r += entity->sn_modulus; + return r; +} + +static int modulus_tx(nr_rlc_entity_am_t *entity, int a) +{ + int r = a - entity->tx_next_ack; + if (r < 0) r += entity->sn_modulus; + return r; +} + +static int sn_in_recv_window(void *_entity, int sn) +{ + nr_rlc_entity_am_t *entity = _entity; + int mod_sn = modulus_rx(entity, sn); + /* we simplify rx_next <= sn < rx_next + am_window_size */ + return mod_sn < entity->window_size; +} + +static int sn_compare_rx(void *_entity, int a, int b) +{ + nr_rlc_entity_am_t *entity = _entity; + return modulus_rx(entity, a) - modulus_rx(entity, b); +} + +static int sn_compare_tx(void *_entity, int a, int b) +{ + nr_rlc_entity_am_t *entity = _entity; + return modulus_tx(entity, a) - modulus_tx(entity, b); +} + +static int segment_already_received(nr_rlc_entity_am_t *entity, + int sn, int so, int size) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int covered; + + while (l != NULL && size > 0) { + if (l->sn == sn) { + if (l->so <= so && so < l->so + l->size) { + covered = l->size - (so - l->so); + size -= covered; + so += covered; + } else if (l->so <= so+size-1 && so+size-1 < l->so + l->size) { + covered = size - (l->so - so); + size -= covered; + } + } + l = l->next; + } + + return size <= 0; +} + +static void consider_retransmission(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *cur, int update_retx) +{ + if (update_retx) + cur->sdu->retx_count++; + + /* let's report max RETX reached for all retx_count >= max_retx_threshold + * (specs say to report if retx_count == max_retx_threshold). + * Upper layers should react (radio link failure), so no big deal actually. + */ + if (update_retx && cur->sdu->retx_count >= entity->max_retx_threshold) { + entity->common.max_retx_reached(entity->common.max_retx_reached_data, + (nr_rlc_entity_t *)entity); + } + + /* let's put in retransmit list even if we are over max_retx_threshold. + * upper layers should deal with this condition, internally it's better + * for the RLC code to keep going with this segment (we only remove + * a segment that was ACKed) + */ + nr_rlc_sdu_segment_list_append(&entity->retransmit_list, + &entity->retransmit_end, + cur); +} + +/* checks that all the bytes of the SDU sn have been received (but SDU + * has not been already processed) + */ +static int sdu_full(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 0; + if (l->is_last) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +/* checks that an SDU has already been delivered */ +static int sdu_delivered(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + return l != NULL && l->data == NULL; +} + +/* check if there is some missing bytes before the last received of SDU sn */ +/* todo: be sure that when no byte was received or the SDU has already been + * processed then the SDU has no missing byte + */ +static int sdu_has_missing_bytes(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; /* data already processed: no missing byte */ + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +static void reassemble_and_deliver(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *pdu; + char sdu[NR_SDU_MAX]; + int so = 0; + int bad_sdu = 0; + + /* go to first segment of sn */ + pdu = entity->rx_list; + while (pdu->sn != sn) + pdu = pdu->next; + + /* reassemble - free 'data' of each segment after processing */ + while (pdu != NULL && pdu->sn == sn) { + int len = pdu->size - (so - pdu->so); + if (so + len > NR_SDU_MAX && !bad_sdu) { + LOG_E(RLC, "%s:%d:%s: bad SDU, too big, discarding\n", + __FILE__, __LINE__, __FUNCTION__); + bad_sdu = 1; + } + if (!bad_sdu && len > 0) { + memcpy(sdu + so, pdu->data, len); + so += len; + } + free(pdu->data); + pdu->data = NULL; + entity->rx_size -= pdu->size; + pdu = pdu->next; + } + + if (bad_sdu) + return; + + /* deliver */ + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + sdu, so); +} + +static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu) +{ + int x = pdu->sn; + + if (sn_compare_rx(entity, x, entity->rx_next_highest) >= 0) + entity->rx_next_highest = (x + 1) % entity->sn_modulus; + + /* todo: room for optimization: we can run through rx_list only once */ + if (sdu_full(entity, x)) { + reassemble_and_deliver(entity, x); + + if (x == entity->rx_highest_status) { + int rx_highest_status = entity->rx_highest_status; + while (sdu_delivered(entity, rx_highest_status)) + rx_highest_status = (rx_highest_status + 1) % entity->sn_modulus; + entity->rx_highest_status = rx_highest_status; + } + + if (x == entity->rx_next) { + /* update rx_next and free all delivered SDUs at the head of the + * rx_list + */ + int rx_next = entity->rx_next; + while (entity->rx_list != NULL && entity->rx_list->data == NULL && + entity->rx_list->sn == rx_next) { + /* free all segments of this SDU */ + do { + nr_rlc_pdu_t *p = entity->rx_list; + entity->rx_list = p->next; + free(p); + } while (entity->rx_list != NULL && + entity->rx_list->sn == rx_next); + rx_next = (rx_next + 1) % entity->sn_modulus; + } + entity->rx_next = rx_next; + } + } + + if (entity->t_reassembly_start) { + if (entity->rx_next_status_trigger == entity->rx_next || + (entity->rx_next_status_trigger == (entity->rx_next + 1) + % entity->sn_modulus && + !sdu_has_missing_bytes(entity, entity->rx_next)) || + (!sn_in_recv_window(entity, entity->rx_next_status_trigger) && + entity->rx_next_status_trigger != + (entity->rx_next + entity->window_size) % entity->sn_modulus)) { + entity->t_reassembly_start = 0; + } + } + + if (entity->t_reassembly_start == 0) { + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_next + 1) % entity->sn_modulus) > 0 || + (entity->rx_next_highest == (entity->rx_next + 1) + % entity->sn_modulus && + sdu_has_missing_bytes(entity, entity->rx_next))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_next_status_trigger = entity->rx_next_highest; + } + } +} + +static void process_received_ack(nr_rlc_entity_am_t *entity, int ack_sn) +{ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + unsigned char sn_set[32768]; /* used to dec retx_count only once per sdu */ + + memset(sn_set, 0, 32768); + +#define IS_SN_SET(b) (sn_set[(b)/8] & (1 << ((b) % 8))) +#define SET_SN(b) do { sn_set[(b)/8] |= (1 << ((b) % 8)); } while (0) + + /* put SDUs from wait and retransmit lists with SN < 'ack_sn' to ack_list */ + + /* process wait list */ + head.next = entity->wait_list; + prev = &head; + cur = entity->wait_list; + while (cur != NULL) { + if (sn_compare_tx(entity, cur->sdu->sn, ack_sn) < 0) { + /* remove from wait list */ + prev->next = cur->next; + /* put the PDU in the ack list */ + entity->ack_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity, + entity->ack_list, cur); + entity->wait_end = prev; + cur = prev->next; + } else { + entity->wait_end = cur; + prev = cur; + cur = cur->next; + } + } + entity->wait_list = head.next; + if (entity->wait_list == NULL) + entity->wait_end = NULL; + + /* process retransmit list */ + head.next = entity->retransmit_list; + prev = &head; + cur = entity->retransmit_list; + while (cur != NULL) { + if (sn_compare_tx(entity, cur->sdu->sn, ack_sn) < 0) { + /* dec. retx_count in case we put this segment back in retransmit list + * in 'process_received_nack' + * do it only once per SDU + */ + if (!IS_SN_SET(cur->sdu->sn)) { + cur->sdu->retx_count--; + SET_SN(cur->sdu->sn); + } + /* remove from retransmit list */ + prev->next = cur->next; + /* put the PDU in the ack list */ + entity->ack_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity, + entity->ack_list, cur); + entity->retransmit_end = prev; + cur = prev->next; + } else { + entity->retransmit_end = cur; + prev = cur; + cur = cur->next; + } + } + entity->retransmit_list = head.next; + if (entity->retransmit_list == NULL) + entity->retransmit_end = NULL; + +#undef IS_BIT_SET +#undef SET_BIT +} + +static int so_overlap(int s1, int e1, int s2, int e2) +{ + if (s1 < s2) { + if (e1 == -1 || e1 >= s2) + return 1; + return 0; + } + if (e2 == -1 || s1 <= e2) + return 1; + return 0; +} + +static void process_nack_sn(nr_rlc_entity_am_t *entity, int nack_sn, + int so_start, int so_end, unsigned char *sn_set) +{ + /* put all SDU segments with SN == 'sn' and with an overlapping so start/end + * to the retransmit list + * source lists are ack list and wait list. + * Not sure if we should consider wait list, isn't the other end supposed + * to only NACK SNs lower than the ACK SN sent in the status PDU, in which + * case all potential SDU segments should all be in ack list when calling + * the current function? in doubt let's accept anything and thus process + * also wait list. + */ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + +#define IS_SN_SET(b) (sn_set[(b)/8] & (1 << ((b) % 8))) +#define SET_SN(b) do { sn_set[(b)/8] |= (1 << ((b) % 8)); } while (0) + + /* check that tx_next_ack <= sn < tx_next */ + if (!(sn_compare_tx(entity, entity->tx_next_ack, nack_sn) <= 0 && + sn_compare_tx(entity, nack_sn, entity->tx_next) < 0)) + return; + + /* process wait list */ + head.next = entity->wait_list; + prev = &head; + cur = entity->wait_list; + while (cur != NULL) { + if (cur->sdu->sn == nack_sn && + so_overlap(so_start, so_end, cur->so, cur->so + cur->size - 1)) { + /* remove from wait list */ + prev->next = cur->next; + cur->next = NULL; + /* consider the SDU segment for retransmission */ + consider_retransmission(entity, cur, !IS_SN_SET(cur->sdu->sn)); + SET_SN(cur->sdu->sn); + entity->wait_end = prev; + cur = prev->next; + } else { + entity->wait_end = cur; + prev = cur; + cur = cur->next; + } + } + entity->wait_list = head.next; + if (entity->wait_list == NULL) + entity->wait_end = NULL; + + /* process ack list */ + head.next = entity->ack_list; + prev = &head; + cur = entity->ack_list; + while (cur != NULL) { + if (cur->sdu->sn == nack_sn && + so_overlap(so_start, so_end, cur->so, cur->so + cur->size - 1)) { + /* remove from ack list */ + prev->next = cur->next; + cur->next = NULL; + /* consider the SDU segment for retransmission */ + consider_retransmission(entity, cur, !IS_SN_SET(cur->sdu->sn)); + SET_SN(cur->sdu->sn); + cur = prev->next; + } else { + prev = cur; + cur = cur->next; + } + } + entity->ack_list = head.next; + +#undef IS_BIT_SET +#undef SET_BIT +} + +static void process_received_nack(nr_rlc_entity_am_t *entity, int nack_sn, + int so_start, int so_end, int range, + unsigned char *sn_set) +{ + int i; + + for (i = 0; i < range; i++) + process_nack_sn(entity, (nack_sn + i) % entity->sn_modulus, + i == 0 ? so_start : 0, + i == range - 1 ? so_end : -1, + sn_set); +} + +static int sdu_segment_in_ack_list_full(nr_rlc_sdu_segment_t *sdu) +{ + int target_count = sdu->sdu->ref_count; + int actual_count = 0; + int sn = sdu->sdu->sn; + + while (sdu != NULL && sdu->sdu->sn == sn) { + actual_count++; + sdu = sdu->next; + } + + return actual_count == target_count; +} + +static void finalize_ack_nack_processing(nr_rlc_entity_am_t *entity) +{ + nr_rlc_sdu_segment_t *cur = entity->ack_list; + int sn; + + /* - send indication of successful delivery for all consecutive acked SDUs + * starting from tx_next_ack. Also free them. + * - update tx_next_ack to the next SN not acked yet + */ + /* todo: send indication of successful delivery as soon as possible as + * the specs say (38.322 5.2.3.1.1). As the code is, if we receive + * ack for SN+2 we won't indicate successful delivery before + * SN+1 has been indicated. + */ + while (cur != NULL && cur->sdu->sn == entity->tx_next_ack && + sdu_segment_in_ack_list_full(cur)) { + entity->tx_size -= cur->sdu->size; + sn = cur->sdu->sn; + entity->common.sdu_successful_delivery( + entity->common.sdu_successful_delivery_data, + (nr_rlc_entity_t *)entity, cur->sdu->upper_layer_id); + while (cur != NULL && cur->sdu->sn == sn) { + nr_rlc_sdu_segment_t *s = cur; + cur = cur->next; + nr_rlc_free_sdu_segment(s); + } + entity->ack_list = cur; + entity->tx_next_ack = (entity->tx_next_ack + 1) % entity->sn_modulus; + } +} + +void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ +#define R(d) do { if (nr_rlc_pdu_decoder_in_error(&d)) goto err; } while (0) + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_pdu_decoder_t decoder; + nr_rlc_pdu_decoder_t control_decoder; + nr_rlc_pdu_t *pdu; + int dc; + int p = 0; + int si; + int sn; + int so = 0; + int data_size; + int is_first; + int is_last; + + int cpt; + int e1; + int e2; + int e3; + int ack_sn; + int nack_sn; + int so_start; + int so_end; + int range; + int control_e1; + int control_e2; + int control_e3; + unsigned char sn_set[32768]; /* used to dec retx_count only once per sdu */ + + nr_rlc_pdu_decoder_init(&decoder, buffer, size); + dc = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + if (dc == 0) goto control; + + /* data PDU */ + p = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + si = nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + + is_first = (si & 0x2) == 0; + is_last = (si & 0x1) == 0; + + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + } + + sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); + R(decoder); + + if (!is_first) { + so = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + if (so == 0) { + LOG_E(RLC, "%s:%d:%s: warning: discard PDU, bad so\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + } + + data_size = size - decoder.byte; + + /* dicard PDU if no data */ + if (data_size <= 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* dicard PDU if rx buffer is full */ + if (entity->rx_size + data_size > entity->rx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + if (!sn_in_recv_window(entity, sn)) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n", + __FILE__, __LINE__, __FUNCTION__, + sn, entity->rx_next); + goto discard; + } + + /* discard segment if all the bytes of the segment are already there */ + if (segment_already_received(entity, sn, so, data_size)) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, already received\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* put in pdu reception list */ + entity->rx_size += data_size; + pdu = nr_rlc_new_pdu(sn, so, is_first, is_last, + buffer + size - data_size, data_size); + entity->rx_list = nr_rlc_pdu_list_add(sn_compare_rx, entity, + entity->rx_list, pdu); + + /* do reception actions (38.322 5.2.3.2.3) */ + reception_actions(entity, pdu); + + if (p) { + /* 38.322 5.3.4 says status triggering should be delayed + * until x < rx_highest_status or x >= rx_next + am_window_size. + * This is not clear (what is x then? we keep the same?). So let's + * trigger no matter what. + * todo: delay status triggering properly + */ + int v = (entity->rx_next + entity->window_size) % entity->sn_modulus; + entity->status_triggered = 1; + if (!(sn_compare_rx(entity, sn, entity->rx_highest_status) < 0 || + sn_compare_rx(entity, sn, v) >= 0)) { + LOG_D(RLC, "%s:%d:%s: warning: STATUS trigger should be delayed, according to specs\n", + __FILE__, __LINE__, __FUNCTION__); + } + } + + return; + +control: + cpt = nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder); + if (cpt != 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n", + __FILE__, __LINE__, __FUNCTION__, cpt); + goto discard; + } + ack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder); + e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + /* r bits */ + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + } else { + nr_rlc_pdu_decoder_get_bits(&decoder, 7); R(decoder); + } + + /* let's try to parse the control PDU once to check consistency */ + control_decoder = decoder; + control_e1 = e1; + while (control_e1) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder); /* NACK_SN */ + control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + /* r bits */ + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 3); R(control_decoder); + } else { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + } + if (control_e2) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOstart */ + nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOend */ + } + if (control_e3) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder); /* NACK range */ + } + } + + /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is + * received for the SN 'poll_sn' + */ + if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0) + entity->t_poll_retransmit_start = 0; + + /* at this point, accept the PDU even if the actual values + * may be incorrect (eg. if so_start > so_end) + */ + process_received_ack(entity, ack_sn); + + if (e1) + memset(sn_set, 0, 32768); + + while (e1) { + nack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder); + e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + e2 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + e3 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + /* r bits */ + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder); + } else { + nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + } + if (e2) { + so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + if (so_end < so_start) { + LOG_W(RLC, "%s:%d:%s: warning, bad so start/end, NACK the whole PDU (sn %d)\n", + __FILE__, __LINE__, __FUNCTION__, nack_sn); + so_start = 0; + so_end = -1; + } + /* special value 0xffff indicates 'all bytes to the end' */ + if (so_end == 0xffff) + so_end = -1; + } else { + so_start = 0; + so_end = -1; + } + if (e3) { + range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder); + } else { + range = 1; + } + process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set); + + /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is + * received for the SN 'poll_sn' + */ + if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 && + sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0) + entity->t_poll_retransmit_start = 0; + } + + finalize_ack_nack_processing(entity); + + return; + +err: + LOG_W(RLC, "%s:%d:%s: error decoding PDU, discarding\n", __FILE__, __LINE__, __FUNCTION__); + goto discard; + +discard: + if (p) + entity->status_triggered = 1; + +#undef R +} + +/*************************************************************************/ +/* TX functions */ +/*************************************************************************/ + +static int is_window_stalling(nr_rlc_entity_am_t *entity) +{ + /* we are stalling if tx_next is not: + * tx_next_ack <= tx_next < tx_next_ack + window_size + */ + return !(sn_compare_tx(entity, entity->tx_next_ack, entity->tx_next) <= 0 && + sn_compare_tx(entity, entity->tx_next, + (entity->tx_next_ack + entity->window_size) % + entity->sn_modulus) < 0); +} + +static void include_poll(nr_rlc_entity_am_t *entity, char *buffer) +{ + /* set the P bit to 1 */ + buffer[0] |= 0x40; + + entity->pdu_without_poll = 0; + entity->byte_without_poll = 0; + + /* set POLL_SN to highest SN submitted to lower layer + * (this is: entity->tx_next - 1) (todo: be sure of this) + */ + entity->poll_sn = (entity->tx_next - 1 + entity->sn_modulus) + % entity->sn_modulus; + + /* start/restart t_poll_retransmit */ + entity->t_poll_retransmit_start = entity->t_current; +} + +static int check_poll_after_pdu_assembly(nr_rlc_entity_am_t *entity) +{ + int retransmission_buffer_empty; + int transmission_buffer_empty; + + /* is transmission buffer empty? */ + if (entity->tx_list == NULL) + transmission_buffer_empty = 1; + else + transmission_buffer_empty = 0; + + /* is retransmission buffer empty? */ + if (entity->retransmit_list == NULL) + retransmission_buffer_empty = 1; + else + retransmission_buffer_empty = 0; + + return (transmission_buffer_empty && retransmission_buffer_empty) || + is_window_stalling(entity); +} + +static int serialize_sdu(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *sdu, char *buffer, int bufsize, + int p) +{ + nr_rlc_pdu_encoder_t encoder; + + /* generate header */ + nr_rlc_pdu_encoder_init(&encoder, buffer, bufsize); + + nr_rlc_pdu_encoder_put_bits(&encoder, 1, 1); /* D/C: 1 = data */ + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 1); /* P: reserve, set later */ + + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_first,1);/* 1st bit of SI */ + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_last,1); /* 2nd bit of SI */ + + if (entity->sn_field_length == 18) + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 2); /* R */ + + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->sdu->sn, + entity->sn_field_length); /* SN */ + + if (!sdu->is_first) + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->so, 16); /* SO */ + + /* data */ + memcpy(buffer + encoder.byte, sdu->sdu->data + sdu->so, sdu->size); + + if (p) + include_poll(entity, buffer); + + return encoder.byte + sdu->size; +} + +/* for a given SDU/SDU segment, computes the corresponding PDU header size */ +static int compute_pdu_header_size(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *sdu) +{ + int header_size = 2; + /* one more byte if SN field length is 18 */ + if (entity->sn_field_length == 18) + header_size++; + /* two more bytes for SO if SDU segment is not the first */ + if (!sdu->is_first) header_size += 2; + return header_size; +} + +/* resize SDU/SDU segment for the corresponding PDU to fit into 'pdu_size' + * bytes + * - modifies SDU/SDU segment to become an SDU segment + * - returns a new SDU segment covering the remaining data bytes + */ +static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu, + nr_rlc_entity_am_t *entity, + int pdu_size) +{ + nr_rlc_sdu_segment_t *next; + int pdu_header_size; + int over_size; + + sdu->sdu->ref_count++; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + next = calloc(1, sizeof(nr_rlc_sdu_segment_t)); + if (next == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + *next = *sdu; + + over_size = pdu_header_size + sdu->size - pdu_size; + + /* update SDU */ + sdu->size -= over_size; + sdu->is_last = 0; + + /* create new segment */ + next->size = over_size; + next->so = sdu->so + sdu->size; + next->is_first = 0; + + return next; +} + +/*************************************************************************/ +/* TX functions - status reporting [begin] */ +/*************************************************************************/ + +typedef struct { + /* data for missing bytes */ + int sn_start; /* set to -1 when no more missing part to report */ + int so_start; + int sn_end; + int so_end; + /* data for maximum ack */ + int ack_sn; /* -1 if not to be used */ + /* pdu to use for next call to 'next_missing' */ + nr_rlc_pdu_t *next; +} missing_data_t; + +/* todo: rewrite this function, too messy */ +static missing_data_t next_missing(nr_rlc_entity_am_t *entity, + nr_rlc_pdu_t *cur, int check_head) +{ + missing_data_t ret; + int cur_max_so; + int sn; + int max_so = 0; + int last_reached = 0; + + ret.ack_sn = -1; + + /* special case: missing part before the head of RX list */ + if (check_head) { + if (cur->sn != entity->rx_next || !cur->is_first) { + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, cur->sn) <= 0) { + ret.sn_start = -1; + return ret; + } + /* the missing part is starting from rx_next(0) + * going to min of: + * - cur->sn(cur->so-1) [if cur->sn is not first] + * or (cur->sn-1)(0xffff) [if cur->sn is first] + * - (entity->rx_highest_status-1)(0xffff) + */ + ret.sn_start = entity->rx_next; + ret.so_start = 0; + goto set_end_different_sdu; + } + } + +next_pdu: + sn = cur->sn; + cur_max_so = cur->so + cur->size - 1; + if (cur_max_so > max_so) + max_so = cur_max_so; + last_reached = last_reached | cur->is_last; + + /* if cur already processed, it can be the acked SDU */ + if (cur->data == NULL) + ret.ack_sn = (cur->sn + 1) % entity->sn_modulus; + + /* no next? */ + if (cur->next == NULL) { + /* inform the caller that work is over */ + ret.next = NULL; + + /* already processed => next SDU to rx_highest_status - 1 to be nacked */ + if (cur->data == NULL) { + ret.sn_start = (cur->sn + 1) % entity->sn_modulus; + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, + ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.so_start = 0; + ret.sn_end = (entity->rx_highest_status - 1 + entity->sn_modulus) % + entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + /* not already processed => all bytes after max_so (if any) then all SDU + * to rx_highest_status-1 to be nacked + */ + if (last_reached) { + ret.sn_start = (cur->sn + 1) % entity->sn_modulus; + ret.so_start = 0; + } else { + ret.sn_start = cur->sn; + ret.so_start = max_so + 1; + } + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, + ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.sn_end = (entity->rx_highest_status - 1 + entity->sn_modulus) % + entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + + cur = cur->next; + + /* no discontinuity in data => process to next PDU */ + if (cur->sn == sn && max_so >= cur->so - 1) + goto next_pdu; + if (cur->sn == (sn + 1) % entity->sn_modulus && last_reached && + cur->is_first) { + last_reached = 0; + max_so = 0; + goto next_pdu; + } + + /* discontinuity in data */ + + /* remember where to start from for the next call */ + ret.next = cur; + + /* discontinuity in same SDU */ + if (cur->sn == sn) { + ret.sn_start = sn; + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, + ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.so_start = max_so + 1; + ret.sn_end = sn; + ret.so_end = cur->so - 1; + return ret; + } + + /* discontinuity between different SDUs */ + ret.sn_start = sn; + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.so_start = max_so + 1; + +set_end_different_sdu: + /* don't go more than rx_highest_status - 1 */ + if (sn_compare_rx(entity, entity->rx_highest_status, cur->sn) <= 0) { + ret.so_end = (entity->rx_highest_status - 1 + entity->sn_modulus) % + entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + + /* if cur is the head of a SDU, then use cur-1 */ + if (cur->is_first) { + ret.sn_end = (cur->sn - 1 + entity->sn_modulus) % entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + + ret.sn_end = cur->sn; + ret.so_end = cur->so - 1; + return ret; +} + +static int nack_size(nr_rlc_entity_am_t *entity, missing_data_t *m) +{ + int nack_length = 2 + (entity->sn_field_length == 18); + + if (m->sn_start == m->sn_end) { + /* only nack_sn, no so_start/end, no nack range */ + if (m->so_start == 0 && m->so_end == 0xffff) + return nack_length; + /* nack_sn + so_start/end */ + return nack_length + 4; + } + + /* nack_sn + nack range, no so_start/end */ + if (m->so_start == 0 && m->so_end == 0xffff) + return nack_length + 1; + + /* nack_sn + so_start/end + nack range */ + return nack_length + 5; +} + +/* returns the e1 byte/bit position supposing the encoder points at + * the beginning of a nack_sn block + */ +static void get_e1_position(nr_rlc_entity_am_t *entity, + nr_rlc_pdu_encoder_t *encoder, + int *e1_byte, int *e1_bit) +{ + if (entity->sn_field_length == 18) { + *e1_byte = encoder->byte + 2; + *e1_bit = 5; + } else { + *e1_byte = encoder->byte + 1; + *e1_bit = 3; + } +} + +/* returns the number of nacks serialized. + * In most cases it is 1, it can be more if the + * missing data consists of a range that is more + * than 255 SNs in which case it has to be cut in + * smaller ranges. + * If there is no more room in the status buffer, + * will set m->next = NULL (and may serialize + * less nacks than required by 'm'). + */ +static int generate_missing(nr_rlc_entity_am_t *entity, + nr_rlc_pdu_encoder_t *encoder, + missing_data_t *m, int *e1_byte, int *e1_bit) +{ + int r_bits = entity->sn_field_length == 18 ? 3 : 1; + int range_count = 0; + int sn_start; + int so_start; + int sn_end; + int so_end; + int sn_count; + missing_data_t m_nack; + int e2; + int e3; + + /* be careful to limit a range to 255 SNs, that is: cut if needed */ + sn_count = (m->sn_end - m->sn_start + entity->sn_modulus) + % entity->sn_modulus + 1; + + sn_start = m->sn_start; + + while (sn_count) { + int cur_sn_count = sn_count; + if (cur_sn_count > 255) + cur_sn_count = 255; + + /* for first range, so_start is the one of the initial range + * for the following ones, it is 0 + */ + if (sn_start == m->sn_start) { + /* first range */ + so_start = m->so_start; + } else { + /* following ranges */ + so_start = 0; + } + + /* for the last range, sn_end/so_end are the ones of the initial range + * for the previous ones, it is sn_start+254/0xffff + */ + if (cur_sn_count == sn_count) { + /* last range */ + sn_end = m->sn_end; + so_end = m->so_end; + } else { + /* previous ranges */ + sn_end = (sn_start + 254) % entity->sn_modulus; + so_end = 0xffff; + } + + /* check that there is room for a nack */ + m_nack.sn_start = sn_start; + m_nack.so_start = so_start; + m_nack.sn_end = sn_end; + m_nack.so_end = so_end; + if (encoder->byte + nack_size(entity, &m_nack) > encoder->size) { + m->next = NULL; + break; + } + + /* set the previous e1 bit to 1 */ + encoder->buffer[*e1_byte] |= 1 << *e1_bit; + + get_e1_position(entity, encoder, e1_byte, e1_bit); + + if (sn_start == sn_end) { + if (so_start == 0 && so_end == 0xffff) { + /* only nack_sn, no so_start/end, no nack range */ + e2 = 0; + e3 = 0; + } else { + /* nack_sn + so_start/end, no nack range */ + e2 = 1; + e3 = 0; + } + } else { + if (so_start == 0 && so_end == 0xffff) { + /* nack_sn + nack range, no so_start/end */ + e2 = 0; + e3 = 1; + } else { + /* nack_sn + so_start/end + nack range */ + e2 = 1; + e3 = 1; + } + } + + /* nack_sn */ + nr_rlc_pdu_encoder_put_bits(encoder, sn_start, + entity->sn_field_length); + /* e1 = 0 (set later if needed) */ + nr_rlc_pdu_encoder_put_bits(encoder, 0, 1); + /* e2 */ + nr_rlc_pdu_encoder_put_bits(encoder, e2, 1); + /* e3 */ + nr_rlc_pdu_encoder_put_bits(encoder, e3, 1); + /* r */ + nr_rlc_pdu_encoder_put_bits(encoder, 0, r_bits); + /* so_start/so_end */ + if (e2) { + nr_rlc_pdu_encoder_put_bits(encoder, so_start, 16); + nr_rlc_pdu_encoder_put_bits(encoder, so_end, 16); + } + /* nack range */ + if (e3) + nr_rlc_pdu_encoder_put_bits(encoder, cur_sn_count, 8); + + sn_count -= cur_sn_count; + sn_start = (sn_start + cur_sn_count) % entity->sn_modulus; + range_count++; + } + + return range_count; +} + +static int generate_status(nr_rlc_entity_am_t *entity, char *buffer, int size) +{ + int ack_sn = entity->rx_next; + missing_data_t m; + nr_rlc_pdu_t *cur; + int nack_count = 0; + nr_rlc_pdu_encoder_t encoder; + int e1_byte; + int e1_bit; + + /* if not enough room, do nothing */ + if (size < 3) + return 0; + + nr_rlc_pdu_encoder_init(&encoder, buffer, size); + + /* first 3 bytes, ack_sn and e1 will be set later */ + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 8*3); + + cur = entity->rx_list; + + /* store the position of the e1 bit to be set if + * there is a nack following + */ + e1_byte = 2; + e1_bit = entity->sn_field_length == 18 ? 1 : 7; + + while (cur != NULL) { + m = next_missing(entity, cur, nack_count == 0); + + /* update ack_sn if the returned value is valid */ + if (m.ack_sn != -1) + ack_sn = m.ack_sn; + + /* stop here if no more nack to report */ + if (m.sn_start == -1) + break; + + nack_count += generate_missing(entity, &encoder, &m, &e1_byte, &e1_bit); + + cur = m.next; + } + + /* put ack_sn */ + if (entity->sn_field_length == 12) { + buffer[0] = ack_sn >> 8; + buffer[1] = ack_sn & 255; + } else { + buffer[0] = ack_sn >> 14; + buffer[1] = (ack_sn >> 6) & 255; + buffer[2] |= (ack_sn & 0x3f) << 2; + } + + /* reset the trigger */ + entity->status_triggered = 0; + + /* start t_status_prohibit */ + entity->t_status_prohibit_start = entity->t_current; + + return encoder.byte; +} + +static int status_to_report(nr_rlc_entity_am_t *entity) +{ + return entity->status_triggered && + (entity->t_status_prohibit_start == 0 || + entity->t_current - entity->t_status_prohibit_start > + entity->t_status_prohibit); +} + +static int missing_size(nr_rlc_entity_am_t *entity, missing_data_t *m, + int *size, int maxsize) +{ + int r_bits = entity->sn_field_length == 18 ? 3 : 1; + int range_count = 0; + int sn_start; + int so_start; + int sn_end; + int so_end; + int sn_count; + missing_data_t m_nack; + + /* be careful to limit a range to 255 SNs, that is: cut if needed */ + sn_count = m->sn_end - m->sn_start; + if (sn_count < 0) + sn_count += entity->sn_modulus; + + sn_start = m->sn_start; + + while (sn_count) { + int cur_sn_count = sn_count; + if (cur_sn_count > 255) + cur_sn_count = 255; + + /* for first range, so_start is the one of the initial range + * for the following ones, it is 0 + */ + if (sn_start == m->sn_start) { + /* first range */ + so_start = m->so_start; + } else { + /* following ranges */ + so_start = 0; + } + + /* for the last range, sn_end/so_end are the ones of the initial range + * for the previous ones, it is sn_start+254/0xffff + */ + if (cur_sn_count == sn_count) { + /* last range */ + sn_end = m->sn_end; + so_end = m->so_end; + } else { + /* previous ranges */ + sn_end = (sn_start + 254) % entity->sn_modulus; + so_end = 0xffff; + } + + /* check that there is room for a nack */ + m_nack.sn_start = sn_start; + m_nack.so_start = so_start; + m_nack.sn_end = sn_end; + m_nack.so_end = so_end; + if (*size + nack_size(entity, &m_nack) > maxsize) { + m->next = NULL; + break; + } + + if (sn_start == sn_end) { + if (so_start == 0 && so_end == 0xffff) { + /* only nack_sn, no so_start/end, no nack range */ + *size += (entity->sn_field_length + 3 + r_bits) / 8; + } else { + /* nack_sn + so_start/end, no nack range */ + *size += (entity->sn_field_length + 3 + r_bits + 16*2) / 8; + } + } else { + if (so_start == 0 && so_end == 0xffff) { + /* nack_sn + nack range, no so_start/end */ + *size += (entity->sn_field_length + 3 + r_bits + 8) / 8; + } else { + /* nack_sn + so_start/end + nack range */ + *size += (entity->sn_field_length + 3 + r_bits + 16*2 + 8) / 8; + } + } + + sn_count -= cur_sn_count; + sn_start = (sn_start + cur_sn_count) % entity->sn_modulus; + range_count++; + } + + return range_count; +} + +static int status_size(nr_rlc_entity_am_t *entity, int maxsize) +{ + missing_data_t m; + nr_rlc_pdu_t *cur; + int nack_count = 0; + int size; + + /* if not enough room, do nothing */ + if (maxsize < 3) + return 0; + + /* minimum 3 bytes */ + size = 3; + + cur = entity->rx_list; + + while (cur != NULL) { + m = next_missing(entity, cur, nack_count == 0); + + /* stop here if no more nack to report */ + if (m.sn_start == -1) + break; + + nack_count += missing_size(entity, &m, &size, maxsize); + + cur = m.next; + } + + return size; +} + +/*************************************************************************/ +/* TX functions - status reporting [end] */ +/*************************************************************************/ + +static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer, + int size) +{ + nr_rlc_sdu_segment_t *sdu; + int pdu_header_size; + int pdu_size; + int p; + + sdu = entity->retransmit_list; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + /* not enough room for at least one byte of data? do nothing */ + if (pdu_header_size + 1 > size) + return 0; + + entity->retransmit_list = entity->retransmit_list->next; + if (entity->retransmit_list == NULL) + entity->retransmit_end = NULL; + + sdu->next = NULL; + + /* segment if necessary */ + pdu_size = pdu_header_size + sdu->size; + if (pdu_size > size) { + nr_rlc_sdu_segment_t *next_sdu; + next_sdu = resegment(sdu, entity, size); + /* put the second SDU back at the head of the retransmit list */ + next_sdu->next = entity->retransmit_list; + entity->retransmit_list = next_sdu; + if (entity->retransmit_end == NULL) + entity->retransmit_end = entity->retransmit_list; + } + + /* put SDU/SDU segment in the wait list */ + nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu); + + p = check_poll_after_pdu_assembly(entity); + + if (entity->force_poll) { + p = 1; + entity->force_poll = 0; + } + + return serialize_sdu(entity, sdu, buffer, size, p); +} + +static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size) +{ + nr_rlc_sdu_segment_t *sdu; + int pdu_header_size; + int pdu_size; + int p; + + /* sn out of window (that is: we have window stalling)? do nothing */ + if (is_window_stalling(entity)) + return 0; + + if (entity->tx_list == NULL) + return 0; + + sdu = entity->tx_list; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + /* not enough room for at least one byte of data? do nothing */ + if (pdu_header_size + 1 > size) + return 0; + + entity->tx_list = entity->tx_list->next; + if (entity->tx_list == NULL) + entity->tx_end = NULL; + + sdu->next = NULL; + + /* assign SN to SDU */ + sdu->sdu->sn = entity->tx_next; + + /* segment if necessary */ + pdu_size = pdu_header_size + sdu->size; + if (pdu_size > size) { + nr_rlc_sdu_segment_t *next_sdu; + next_sdu = resegment(sdu, entity, size); + /* put the second SDU back at the head of the TX list */ + next_sdu->next = entity->tx_list; + entity->tx_list = next_sdu; + if (entity->tx_end == NULL) + entity->tx_end = entity->tx_list; + } + + /* update tx_next if the SDU segment is the last */ + if (sdu->is_last) + entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus; + + /* put SDU/SDU segment in the wait list */ + nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu); + + /* polling actions for a new PDU */ + entity->pdu_without_poll++; + entity->byte_without_poll += sdu->size; + if ((entity->poll_pdu != -1 && + entity->pdu_without_poll >= entity->poll_pdu) || + (entity->poll_byte != -1 && + entity->byte_without_poll >= entity->poll_byte)) + p = 1; + else + p = check_poll_after_pdu_assembly(entity); + + if (entity->force_poll) { + p = 1; + entity->force_poll = 0; + } + + return serialize_sdu(entity, sdu, buffer, size, p); +} + +/* Pretend to serialize all the SDUs in a list and return the size + * of all the PDUs it would produce, limited to 'maxsize'. + * Used for buffer status reporting. + */ +static int tx_list_size(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *l, int maxsize) +{ + int ret = 0; + + while (l != NULL) { + ret += compute_pdu_header_size(entity, l) + l->size; + l = l->next; + } + + if (ret > maxsize) ret = maxsize; + return ret; +} + +nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status( + nr_rlc_entity_t *_entity, int maxsize) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_entity_buffer_status_t ret; + + if (status_to_report(entity)) + ret.status_size = status_size(entity, maxsize); + else + ret.status_size = 0; + + ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize); + ret.retx_size = tx_list_size(entity, entity->retransmit_list, maxsize); + + return ret; +} + +int nr_rlc_entity_am_generate_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + int ret; + + if (status_to_report(entity)) { + ret = generate_status(entity, buffer, size); + if (ret != 0) + return ret; + } + + if (entity->retransmit_list != NULL) { + ret = generate_retx_pdu(entity, buffer, size); + if (ret != 0) + return ret; + } + + return generate_tx_pdu(entity, buffer, size); +} + +/*************************************************************************/ +/* SDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity, + char *buffer, int size, + int sdu_id) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_sdu_segment_t *sdu; + + if (size > NR_SDU_MAX) { + LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", + __FILE__, __LINE__, __FUNCTION__, size); + exit(1); + } + + if (entity->tx_size + size > entity->tx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + entity->tx_size += size; + + sdu = nr_rlc_new_sdu(buffer, size, sdu_id); + + nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu); +} + +/*************************************************************************/ +/* time/timers */ +/*************************************************************************/ + +static void check_t_poll_retransmit(nr_rlc_entity_am_t *entity) +{ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + int sn; + int old_retx_count; + + /* 38.322 5.3.3.4 */ + /* did t_poll_retransmit expire? */ + if (entity->t_poll_retransmit_start == 0 || + entity->t_current <= entity->t_poll_retransmit_start + + entity->t_poll_retransmit) + return; + + /* stop timer */ + entity->t_poll_retransmit_start = 0; + + /* 38.322 5.3.3.4 says: + * + * - include a poll in a RLC data PDU as described in section 5.3.3.2 + * + * That does not seem to be conditional. So we forcefully will send + * a poll as soon as we generate a PDU. + * Hopefully this interpretation is correct. In the worst case we generate + * more polling than necessary, but it's not a big deal. When + * 't_poll_retransmit' expires it means we didn't receive a status report, + * meaning a bad radio link, so things are quite bad at this point and + * asking again for a poll won't hurt much more. + */ + entity->force_poll = 1; + + LOG_D(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n", + __FILE__, __LINE__, __FUNCTION__); + + /* do we meet conditions of 38.322 5.3.3.4? */ + if (!check_poll_after_pdu_assembly(entity)) + return; + + /* search wait list for SDU with highest SN */ + /* this code may be incorrect: in LTE we had to look for PDU + * with SN = VT(S) - 1, but for NR the specs say "highest SN among the + * ones submitted to lower layers" not 'tx_next - 1'. So we should look + * for the highest SN in the wait list. But that's no big deal. If the + * program runs this code, then the connection is in a bad state and we + * can retransmit whatever we want. At some point we will receive a status + * report and retransmit what we really have to. Actually we could just + * retransmit the head of wait list (the specs have this 'or'). + * (Actually, maybe this interpretation is not correct and what the code + * does is correct. The specs are confusing.) + */ + sn = (entity->tx_next - 1 + entity->sn_modulus) % entity->sn_modulus; + + head.next = entity->wait_list; + cur = entity->wait_list; + prev = &head; + + while (cur != NULL) { + if (cur->sdu->sn == sn) + break; + prev = cur; + cur = cur->next; + } + + /* SDU with highest SN not found? take the head of wait list */ + if (cur == NULL) { + cur = entity->wait_list; + prev = &head; + sn = cur->sdu->sn; + } + + /* todo: do we need to for check cur == NULL? + * It seems that no, the wait list should not be empty here, but not sure. + */ + + old_retx_count = cur->sdu->retx_count; + + /* 38.322 says "SDU", not "SDU segment", so let's retransmit all + * SDU segments with this SN + */ + /* todo: maybe we could simply retransmit the current SDU segment, + * so that we don't have to run through the full wait list. + */ + while (cur != NULL) { + if (cur->sdu->sn == sn) { + prev->next = cur->next; + cur->next = NULL; + /* put in retransmit list */ + consider_retransmission(entity, cur, + old_retx_count == cur->sdu->retx_count); + } else { + prev = cur; + } + cur = prev->next; + } + entity->wait_list = head.next; + /* reset wait_end (todo: optimize?) */ + entity->wait_end = entity->wait_list; + while (entity->wait_end != NULL && entity->wait_end->next != NULL) + entity->wait_end = entity->wait_end->next; +} + +static void check_t_reassembly(nr_rlc_entity_am_t *entity) +{ + int sn; + + /* is t_reassembly running and if yes has it expired? */ + if (entity->t_reassembly_start == 0 || + entity->t_current <= entity->t_reassembly_start + entity->t_reassembly) + return; + + /* stop timer */ + entity->t_reassembly_start = 0; + + LOG_D(RLC, "%s:%d:%s: t_reassembly expired\n", + __FILE__, __LINE__, __FUNCTION__); + + /* update RX_Highest_Status */ + sn = entity->rx_next_status_trigger; + while (sdu_delivered(entity, sn)) + sn = (sn + 1) % entity->sn_modulus; + entity->rx_highest_status = sn; + + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_highest_status+1) % entity->sn_modulus) > 0 || + (entity->rx_next_highest == + (entity->rx_highest_status+1) % entity->sn_modulus && + sdu_has_missing_bytes(entity, entity->rx_highest_status))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_next_status_trigger = entity->rx_next_highest; + } +} + +void nr_rlc_entity_am_set_time(nr_rlc_entity_t *_entity, uint64_t now) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + + entity->t_current = now; + + check_t_poll_retransmit(entity); + + check_t_reassembly(entity); +} + +/*************************************************************************/ +/* discard/re-establishment/delete */ +/*************************************************************************/ + +void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id) +{ + /* implements 38.322 5.4 */ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + + head.next = entity->tx_list; + cur = entity->tx_list; + prev = &head; + + while (cur != NULL && cur->sdu->upper_layer_id != sdu_id) { + prev = cur; + cur = cur->next; + } + + /* if sdu_id not found or some bytes have already been 'PDU-ized' + * then do nothing + */ + if (cur == NULL || !cur->is_first || !cur->is_last) + return; + + /* remove SDU from tx_list */ + prev->next = cur->next; + entity->tx_list = head.next; + if (entity->tx_end == cur) { + if (prev != &head) + entity->tx_end = prev; + else + entity->tx_end = NULL; + } + + nr_rlc_free_sdu_segment(cur); +} + +static void clear_entity(nr_rlc_entity_am_t *entity) +{ + nr_rlc_pdu_t *cur_rx; + + entity->rx_next = 0; + entity->rx_next_status_trigger = 0; + entity->rx_highest_status = 0; + entity->rx_next_highest = 0; + + entity->status_triggered = 0; + + entity->tx_next = 0; + entity->tx_next_ack = 0; + entity->poll_sn = 0; + entity->pdu_without_poll = 0; + entity->byte_without_poll = 0; + entity->force_poll = 0; + + entity->t_current = 0; + + entity->t_poll_retransmit_start = 0; + entity->t_reassembly_start = 0; + entity->t_status_prohibit_start = 0; + + cur_rx = entity->rx_list; + while (cur_rx != NULL) { + nr_rlc_pdu_t *p = cur_rx; + cur_rx = cur_rx->next; + nr_rlc_free_pdu(p); + } + entity->rx_list = NULL; + entity->rx_size = 0; + + nr_rlc_free_sdu_segment_list(entity->tx_list); + nr_rlc_free_sdu_segment_list(entity->wait_list); + nr_rlc_free_sdu_segment_list(entity->retransmit_list); + nr_rlc_free_sdu_segment_list(entity->ack_list); + + entity->tx_list = NULL; + entity->tx_end = NULL; + entity->tx_size = 0; + + entity->wait_list = NULL; + entity->wait_end = NULL; + + entity->retransmit_list = NULL; + entity->retransmit_end = NULL; + + entity->ack_list = NULL; +} + +void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + clear_entity(entity); +} + +void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + clear_entity(entity); + free(entity); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h new file mode 100644 index 0000000000..7a553a22a9 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h @@ -0,0 +1,102 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_AM_H_ +#define _NR_RLC_ENTITY_AM_H_ + +#include "nr_rlc_entity.h" +#include "nr_rlc_sdu.h" +#include "nr_rlc_pdu.h" + +typedef struct { + nr_rlc_entity_t common; + + /* configuration */ + int t_poll_retransmit; + int t_reassembly; + int t_status_prohibit; + int poll_pdu; /* -1 means infinity */ + int poll_byte; /* -1 means infinity */ + int max_retx_threshold; + int sn_field_length; + + int sn_modulus; + int window_size; + + /* runtime rx */ + int rx_next; + int rx_next_status_trigger; + int rx_highest_status; + int rx_next_highest; + + int status_triggered; + + /* runtime tx */ + int tx_next; + int tx_next_ack; + int poll_sn; + int pdu_without_poll; + int byte_without_poll; + int force_poll; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* timers (stores the TTI of activation, 0 means not active) */ + uint64_t t_poll_retransmit_start; + uint64_t t_reassembly_start; + uint64_t t_status_prohibit_start; + + /* rx management */ + nr_rlc_pdu_t *rx_list; + int rx_size; + int rx_maxsize; + + /* tx management */ + nr_rlc_sdu_segment_t *tx_list; + nr_rlc_sdu_segment_t *tx_end; + int tx_size; + int tx_maxsize; + + nr_rlc_sdu_segment_t *wait_list; + nr_rlc_sdu_segment_t *wait_end; + + nr_rlc_sdu_segment_t *retransmit_list; + nr_rlc_sdu_segment_t *retransmit_end; + + nr_rlc_sdu_segment_t *ack_list; +} nr_rlc_entity_am_t; + +void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *entity, + char *buffer, int size, + int sdu_id); +void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status( + nr_rlc_entity_t *entity, int maxsize); +int nr_rlc_entity_am_generate_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +void nr_rlc_entity_am_set_time(nr_rlc_entity_t *entity, uint64_t now); +void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); +void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity); +void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_ENTITY_AM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c new file mode 100644 index 0000000000..86a0697624 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c @@ -0,0 +1,181 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity_tm.h" + +#include +#include + +#include "nr_rlc_pdu.h" + +#include "LOG/log.h" + +/*************************************************************************/ +/* PDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + buffer, size); +} + +/*************************************************************************/ +/* TX functions */ +/*************************************************************************/ + +static int generate_tx_pdu(nr_rlc_entity_tm_t *entity, char *buffer, int size) +{ + nr_rlc_sdu_segment_t *sdu; + int ret; + + if (entity->tx_list == NULL) + return 0; + + sdu = entity->tx_list; + + /* not enough room? do nothing */ + if (sdu->size > size) + return 0; + + entity->tx_list = entity->tx_list->next; + if (entity->tx_list == NULL) + entity->tx_end = NULL; + + ret = sdu->size; + + memcpy(buffer, sdu->sdu->data, sdu->size); + + entity->tx_size -= sdu->size; + nr_rlc_free_sdu_segment(sdu); + + return ret; +} + +static int tx_list_size(nr_rlc_entity_tm_t *entity, + nr_rlc_sdu_segment_t *l, int maxsize) +{ + int ret = 0; + + while (l != NULL) { + ret += l->size; + l = l->next; + } + + if (ret > maxsize) ret = maxsize; + return ret; +} + +nr_rlc_entity_buffer_status_t nr_rlc_entity_tm_buffer_status( + nr_rlc_entity_t *_entity, int maxsize) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + nr_rlc_entity_buffer_status_t ret; + + ret.status_size = 0; + ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize); + ret.retx_size = 0; + + return ret; +} + +int nr_rlc_entity_tm_generate_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + + return generate_tx_pdu(entity, buffer, size); +} + +/*************************************************************************/ +/* SDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity, + char *buffer, int size, + int sdu_id) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + nr_rlc_sdu_segment_t *sdu; + + if (size > NR_SDU_MAX) { + LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", + __FILE__, __LINE__, __FUNCTION__, size); + exit(1); + } + + if (entity->tx_size + size > entity->tx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + entity->tx_size += size; + + sdu = nr_rlc_new_sdu(buffer, size, sdu_id); + + nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu); +} + +/*************************************************************************/ +/* time/timers */ +/*************************************************************************/ + +void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *_entity, uint64_t now) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + + entity->t_current = now; +} + +/*************************************************************************/ +/* discard/re-establishment/delete */ +/*************************************************************************/ + +void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id) +{ + /* nothing to do */ +} + +static void clear_entity(nr_rlc_entity_tm_t *entity) +{ + nr_rlc_free_sdu_segment_list(entity->tx_list); + + entity->tx_list = NULL; + entity->tx_end = NULL; + entity->tx_size = 0; +} + +void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + clear_entity(entity); +} + +void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + clear_entity(entity); + free(entity); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h new file mode 100644 index 0000000000..7c8c7e40a0 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_TM_H_ +#define _NR_RLC_ENTITY_TM_H_ + +#include "nr_rlc_entity.h" +#include "nr_rlc_sdu.h" + +typedef struct { + nr_rlc_entity_t common; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* tx management */ + nr_rlc_sdu_segment_t *tx_list; + nr_rlc_sdu_segment_t *tx_end; + int tx_size; + int tx_maxsize; +} nr_rlc_entity_tm_t; + +void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *entity, + char *buffer, int size, + int sdu_id); +void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +nr_rlc_entity_buffer_status_t nr_rlc_entity_tm_buffer_status( + nr_rlc_entity_t *entity, int maxsize); +int nr_rlc_entity_tm_generate_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *entity, uint64_t now); +void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); +void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity); +void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_ENTITY_TM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c new file mode 100644 index 0000000000..09f29ebe67 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -0,0 +1,697 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity_um.h" + +#include +#include + +#include "nr_rlc_pdu.h" + +#include "LOG/log.h" + +/*************************************************************************/ +/* PDU RX functions */ +/*************************************************************************/ + +static int modulus_rx(nr_rlc_entity_um_t *entity, int a) +{ + /* as per 38.322 7.1, modulus base is rx_next_highest - window_size */ + int r = a - (entity->rx_next_highest - entity->window_size); + if (r < 0) r += entity->sn_modulus; + return r % entity->sn_modulus; +} + +static int sn_compare_rx(void *_entity, int a, int b) +{ + nr_rlc_entity_um_t *entity = _entity; + return modulus_rx(entity, a) - modulus_rx(entity, b); +} + +/* checks that all the bytes of the SDU sn have been received (but SDU + * has not been already processed) + */ +static int sdu_full(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 0; + if (l->is_last) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +/* checks that an SDU has already been delivered */ +static int sdu_delivered(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + return l != NULL && l->data == NULL; +} + +/* check if there is some missing bytes before the last received of SDU sn */ +/* todo: be sure that when no byte was received or the SDU has already been + * processed then the SDU has no missing byte + */ +static int sdu_has_missing_bytes(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; /* data already processed: no missing byte */ + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +static void reassemble_and_deliver(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *pdu; + char sdu[NR_SDU_MAX]; + int so = 0; + int bad_sdu = 0; + + /* go to first segment of sn */ + pdu = entity->rx_list; + while (pdu->sn != sn) + pdu = pdu->next; + + /* reassemble - free 'data' of each segment after processing */ + while (pdu != NULL && pdu->sn == sn) { + int len = pdu->size - (so - pdu->so); + if (so + len > NR_SDU_MAX && !bad_sdu) { + LOG_E(RLC, "%s:%d:%s: bad SDU, too big, discarding\n", + __FILE__, __LINE__, __FUNCTION__); + bad_sdu = 1; + } + if (!bad_sdu && len > 0) { + memcpy(sdu + so, pdu->data, len); + so += len; + } + free(pdu->data); + pdu->data = NULL; + entity->rx_size -= pdu->size; + pdu->size = 0; + pdu = pdu->next; + } + + if (bad_sdu) + return; + + /* deliver */ + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + sdu, so); +} + +static void reception_actions(nr_rlc_entity_um_t *entity, nr_rlc_pdu_t *pdu) +{ + int x = pdu->sn; + + if (sdu_full(entity, x)) { + /* SDU full */ + reassemble_and_deliver(entity, x); + + if (x == entity->rx_next_reassembly) { + int rx_next_reassembly = entity->rx_next_reassembly; + while (sdu_delivered(entity, rx_next_reassembly)) + rx_next_reassembly = (rx_next_reassembly + 1) % entity->sn_modulus; + entity->rx_next_reassembly = rx_next_reassembly; + } + } else { + /* SDU not full */ + /* test if x is not in reassembly window, that is x >= rx_next_highest */ + if (sn_compare_rx(entity, x, entity->rx_next_highest) >= 0) { + entity->rx_next_highest = (x + 1) % entity->sn_modulus; + + /* discard PDUs not in reassembly window */ + while (entity->rx_list != NULL && + sn_compare_rx(entity, entity->rx_list->sn, + entity->rx_next_highest) >= 0) { + nr_rlc_pdu_t *p = entity->rx_list; + entity->rx_size -= p->size; + entity->rx_list = p->next; + nr_rlc_free_pdu(p); + } + + /* if rx_next_reassembly not in reassembly window */ + if (sn_compare_rx(entity, entity->rx_next_reassembly, + entity->rx_next_highest) >= 0) { + int rx_next_reassembly; + /* set rx_next_reassembly to first SN >= rx_next_highest - window_size + * not delivered yet + */ + rx_next_reassembly = (entity->rx_next_highest - entity->window_size + + entity->sn_modulus) % entity->sn_modulus; + while (sdu_delivered(entity, rx_next_reassembly)) + rx_next_reassembly = (rx_next_reassembly + 1) % entity->sn_modulus; + entity->rx_next_reassembly = rx_next_reassembly; + } + } + } + + if (entity->t_reassembly_start) { + if (/* rx_timer_trigger <= rx_next_reassembly */ + sn_compare_rx(entity, entity->rx_timer_trigger, + entity->rx_next_reassembly) <= 0 || + /* or rx_timer_trigger outside of reassembly window and not equal + * to rx_next_highest, that is is > rx_next_highest + */ + sn_compare_rx(entity, entity->rx_timer_trigger, + entity->rx_next_highest) > 0 || + /* or rx_next_highest == rx_next_reassembly + 1 and no missing byte + * for rx_next_reassembly + */ + (entity->rx_next_highest == (entity->rx_next_reassembly + 1) % + entity->sn_modulus && + !sdu_has_missing_bytes(entity, entity->rx_next_reassembly))) + entity->t_reassembly_start = 0; + } + + if (entity->t_reassembly_start == 0) { + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_next_reassembly + 1) + % entity->sn_modulus) > 0 || + (entity->rx_next_highest == (entity->rx_next_reassembly + 1) + % entity->sn_modulus && + sdu_has_missing_bytes(entity, entity->rx_next_reassembly))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_timer_trigger = entity->rx_next_highest; + } + } +} + +void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ +#define R(d) do { if (nr_rlc_pdu_decoder_in_error(&d)) goto err; } while (0) + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_pdu_decoder_t decoder; + nr_rlc_pdu_t *pdu; + int si; + int sn; + int so = 0; + int data_size; + int is_first; + int is_last; + + nr_rlc_pdu_decoder_init(&decoder, buffer, size); + + si = nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + + is_first = (si & 0x2) == 0; + is_last = (si & 0x1) == 0; + + /* if full, deliver SDU */ + if (is_first && is_last) { + if (size < 2) { + LOG_E(RLC, "%s:%d:%s: warning: discard PDU, no data\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + /* deliver */ + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + buffer + 1, size - 1); + return; + } + + if (entity->sn_field_length == 12) { + nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + } + + sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); + R(decoder); + + if (!is_first) { + so = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + if (so == 0) { + LOG_E(RLC, "%s:%d:%s: warning: discard PDU, bad so\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + } + + data_size = size - decoder.byte; + + /* dicard PDU if no data */ + if (data_size <= 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* dicard PDU if rx buffer is full */ + if (entity->rx_size + data_size > entity->rx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* discard PDU if sn < rx_next_reassembly */ + if (sn_compare_rx(entity, sn, entity->rx_next_reassembly) < 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, SN (%d) < rx_next_reassembly (%d)\n", + __FILE__, __LINE__, __FUNCTION__, + sn, entity->rx_next_reassembly); + goto discard; + } + + /* put in pdu reception list */ + entity->rx_size += data_size; + pdu = nr_rlc_new_pdu(sn, so, is_first, is_last, + buffer + size - data_size, data_size); + entity->rx_list = nr_rlc_pdu_list_add(sn_compare_rx, entity, + entity->rx_list, pdu); + + /* do reception actions (38.322 5.2.2.2.3) */ + reception_actions(entity, pdu); + + return; + +err: + LOG_W(RLC, "%s:%d:%s: error decoding PDU, discarding\n", __FILE__, __LINE__, __FUNCTION__); + goto discard; + +discard: + return; + +#undef R +} + +/*************************************************************************/ +/* TX functions */ +/*************************************************************************/ + +static int serialize_sdu(nr_rlc_entity_um_t *entity, + nr_rlc_sdu_segment_t *sdu, char *buffer, int bufsize) +{ + nr_rlc_pdu_encoder_t encoder; + + /* generate header */ + nr_rlc_pdu_encoder_init(&encoder, buffer, bufsize); + + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_first,1);/* 1st bit of SI */ + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_last,1); /* 2nd bit of SI */ + + /* SN, if required */ + if (sdu->is_first == 1 && sdu->is_last == 1) { + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 6); /* R */ + } else { + if (entity->sn_field_length == 12) + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 2); /* R */ + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->sdu->sn, + entity->sn_field_length); /* SN */ + } + + if (!sdu->is_first) + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->so, 16); /* SO */ + + /* data */ + memcpy(buffer + encoder.byte, sdu->sdu->data + sdu->so, sdu->size); + + return encoder.byte + sdu->size; +} + +/* for a given SDU/SDU segment, computes the corresponding PDU header size */ +static int compute_pdu_header_size(nr_rlc_entity_um_t *entity, + nr_rlc_sdu_segment_t *sdu) +{ + int header_size = 1; + + /* if SN to be included then one more byte if SN field length is 12 */ + if (!(sdu->is_first && sdu->is_last) && entity->sn_field_length == 12) + header_size++; + /* two more bytes for SO if SDU segment is not the first */ + if (!sdu->is_first) header_size += 2; + return header_size; +} + +/* resize SDU/SDU segment for the corresponding PDU to fit into 'pdu_size' + * bytes + * - modifies SDU/SDU segment to become an SDU segment + * - returns a new SDU segment covering the remaining data bytes + * returns NULL if pdu_size is too small to contain the new segment + */ +static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu, + nr_rlc_entity_um_t *entity, + int pdu_size) +{ + nr_rlc_sdu_segment_t *next; + int pdu_header_size; + int over_size; + int old_is_last; + + sdu->sdu->ref_count++; + + /* clear is_last to compute header size */ + old_is_last = sdu->is_last; + sdu->is_last = 0; + pdu_header_size = compute_pdu_header_size(entity, sdu); + sdu->is_last = old_is_last; + + /* if no room for at least 1 data byte, do nothing */ + if (pdu_header_size + 1 > pdu_size) + return NULL; + + next = calloc(1, sizeof(nr_rlc_sdu_segment_t)); + if (next == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + *next = *sdu; + + over_size = pdu_header_size + sdu->size - pdu_size; + + /* update SDU */ + sdu->size -= over_size; + sdu->is_last = 0; + + /* create new segment */ + next->size = over_size; + next->so = sdu->so + sdu->size; + next->is_first = 0; + + return next; +} + +static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size) +{ + nr_rlc_sdu_segment_t *sdu; + int pdu_header_size; + int pdu_size; + int ret; + + if (entity->tx_list == NULL) + return 0; + + sdu = entity->tx_list; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + /* not enough room for at least one byte of data? do nothing */ + if (pdu_header_size + 1 > size) + return 0; + + entity->tx_list = entity->tx_list->next; + if (entity->tx_list == NULL) + entity->tx_end = NULL; + + /* assign SN to SDU */ + sdu->sdu->sn = entity->tx_next; + + /* segment if necessary */ + pdu_size = pdu_header_size + sdu->size; + if (pdu_size > size) { + nr_rlc_sdu_segment_t *next_sdu; + next_sdu = resegment(sdu, entity, size); + if (next_sdu == NULL) + return 0; + /* put the second SDU back at the head of the TX list */ + next_sdu->next = entity->tx_list; + entity->tx_list = next_sdu; + if (entity->tx_end == NULL) + entity->tx_end = entity->tx_list; + } + + /* update tx_next if the SDU is an SDU segment and is the last */ + if (!sdu->is_first && sdu->is_last) + entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus; + + ret = serialize_sdu(entity, sdu, buffer, size); + + entity->tx_size -= sdu->size; + nr_rlc_free_sdu_segment(sdu); + + return ret; +} + +/* Pretend to serialize all the SDUs in a list and return the size + * of all the PDUs it would produce, limited to 'maxsize'. + * Used for buffer status reporting. + */ +static int tx_list_size(nr_rlc_entity_um_t *entity, + nr_rlc_sdu_segment_t *l, int maxsize) +{ + int ret = 0; + + while (l != NULL) { + ret += compute_pdu_header_size(entity, l) + l->size; + l = l->next; + } + + if (ret > maxsize) ret = maxsize; + return ret; +} + +nr_rlc_entity_buffer_status_t nr_rlc_entity_um_buffer_status( + nr_rlc_entity_t *_entity, int maxsize) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_entity_buffer_status_t ret; + + ret.status_size = 0; + ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize); + ret.retx_size = 0; + + return ret; +} + +int nr_rlc_entity_um_generate_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + + return generate_tx_pdu(entity, buffer, size); +} + +/*************************************************************************/ +/* SDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity, + char *buffer, int size, + int sdu_id) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_sdu_segment_t *sdu; + + if (size > NR_SDU_MAX) { + LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", + __FILE__, __LINE__, __FUNCTION__, size); + exit(1); + } + + if (entity->tx_size + size > entity->tx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + entity->tx_size += size; + + sdu = nr_rlc_new_sdu(buffer, size, sdu_id); + + nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu); +} + +/*************************************************************************/ +/* time/timers */ +/*************************************************************************/ + +static void check_t_reassembly(nr_rlc_entity_um_t *entity) +{ + nr_rlc_pdu_t *cur; + + /* is t_reassembly running and if yes has it expired? */ + if (entity->t_reassembly_start == 0 || + entity->t_current <= entity->t_reassembly_start + entity->t_reassembly) + return; + + /* stop timer */ + entity->t_reassembly_start = 0; + + LOG_D(RLC, "%s:%d:%s: t_reassembly expired\n", + __FILE__, __LINE__, __FUNCTION__); + + /* update rx_next_reassembly to first SN >= rx_timer_trigger not reassembled + * (ie. not delivered yet) + */ + entity->rx_next_reassembly = entity->rx_timer_trigger; + while (sdu_delivered(entity, entity->rx_next_reassembly)) + entity->rx_next_reassembly = (entity->rx_next_reassembly + 1) + % entity->sn_modulus; + + /* discard all segments < entity->rx_next_reassembly */ + cur = entity->rx_list; + while (cur != NULL && + sn_compare_rx(entity, cur->sn, entity->rx_next_reassembly) < 0) { + nr_rlc_free_pdu(cur); + cur = cur->next; + entity->rx_list = cur; + } + + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_next_reassembly + 1) + % entity->sn_modulus) > 0 || + (entity->rx_next_highest == entity->rx_next_reassembly + 1 && + sdu_has_missing_bytes(entity, entity->rx_next_reassembly))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_timer_trigger = entity->rx_next_highest; + } +} + +void nr_rlc_entity_um_set_time(nr_rlc_entity_t *_entity, uint64_t now) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + + entity->t_current = now; + + check_t_reassembly(entity); +} + +/*************************************************************************/ +/* discard/re-establishment/delete */ +/*************************************************************************/ + +void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id) +{ + /* implements 38.322 5.4 */ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + + head.next = entity->tx_list; + cur = entity->tx_list; + prev = &head; + + while (cur != NULL && cur->sdu->upper_layer_id != sdu_id) { + prev = cur; + cur = cur->next; + } + + /* if sdu_id not found or some bytes have already been 'PDU-ized' + * then do nothing + */ + if (cur == NULL || !cur->is_first || !cur->is_last) + return; + + /* remove SDU from tx_list */ + prev->next = cur->next; + entity->tx_list = head.next; + if (entity->tx_end == cur) { + if (prev != &head) + entity->tx_end = prev; + else + entity->tx_end = NULL; + } + + nr_rlc_free_sdu_segment(cur); +} + +static void clear_entity(nr_rlc_entity_um_t *entity) +{ + nr_rlc_pdu_t *cur_rx; + + entity->rx_next_highest = 0; + entity->rx_next_reassembly = 0; + entity->rx_timer_trigger = 0; + + + entity->tx_next = 0; + + entity->t_current = 0; + + entity->t_reassembly_start = 0; + + cur_rx = entity->rx_list; + while (cur_rx != NULL) { + nr_rlc_pdu_t *p = cur_rx; + cur_rx = cur_rx->next; + nr_rlc_free_pdu(p); + } + entity->rx_list = NULL; + entity->rx_size = 0; + + nr_rlc_free_sdu_segment_list(entity->tx_list); + + entity->tx_list = NULL; + entity->tx_end = NULL; + entity->tx_size = 0; +} + +void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + clear_entity(entity); +} + +void nr_rlc_entity_um_delete(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + clear_entity(entity); + free(entity); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h new file mode 100644 index 0000000000..21063a1ea1 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h @@ -0,0 +1,79 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_UM_H_ +#define _NR_RLC_ENTITY_UM_H_ + +#include "nr_rlc_entity.h" +#include "nr_rlc_sdu.h" +#include "nr_rlc_pdu.h" + +typedef struct { + nr_rlc_entity_t common; + + /* configuration */ + int t_reassembly; + int sn_field_length; + + int sn_modulus; + int window_size; + + /* runtime rx */ + int rx_next_highest; + int rx_next_reassembly; + int rx_timer_trigger; + + /* runtime tx */ + int tx_next; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* timers (stores the TTI of activation, 0 means not active) */ + uint64_t t_reassembly_start; + + /* rx management */ + nr_rlc_pdu_t *rx_list; + int rx_size; + int rx_maxsize; + + /* tx management */ + nr_rlc_sdu_segment_t *tx_list; + nr_rlc_sdu_segment_t *tx_end; + int tx_size; + int tx_maxsize; +} nr_rlc_entity_um_t; + +void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *entity, + char *buffer, int size, + int sdu_id); +void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +nr_rlc_entity_buffer_status_t nr_rlc_entity_um_buffer_status( + nr_rlc_entity_t *entity, int maxsize); +int nr_rlc_entity_um_generate_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +void nr_rlc_entity_um_set_time(nr_rlc_entity_t *entity, uint64_t now); +void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); +void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity); +void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_ENTITY_UM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c new file mode 100644 index 0000000000..8ee8cdc1c0 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -0,0 +1,874 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* from openair */ +#include "rlc.h" +#include "pdcp.h" + +/* from nr rlc module */ +#include "asn1_utils.h" +#include "nr_rlc_ue_manager.h" +#include "nr_rlc_entity.h" + +#include + +static nr_rlc_ue_manager_t *nr_rlc_ue_manager; + +/* TODO: handle time a bit more properly */ +static uint64_t nr_rlc_current_time; +static int nr_rlc_current_time_last_frame; +static int nr_rlc_current_time_last_subframe; + +void mac_rlc_data_ind ( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + char *buffer_pP, + const tb_size_t tb_sizeP, + num_tb_t num_tbP, + crc_t *crcs_pP) +{ + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + + if (module_idP != 0 || eNB_index != 0 || /*enb_flagP != 1 ||*/ MBMS_flagP != 0) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (enb_flagP) + T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(rntiP), + T_INT(channel_idP), T_INT(tb_sizeP)); + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + rb->set_time(rb, nr_rlc_current_time); + rb->recv_pdu(rb, buffer_pP, tb_sizeP); + } else { + LOG_E(RLC, "%s:%d:%s: fatal: no RB found (channel ID %d)\n", + __FILE__, __LINE__, __FUNCTION__, channel_idP); + exit(1); + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +tbs_size_t mac_rlc_data_req( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + char *buffer_pP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) +{ + int ret; + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + int is_enb; + int maxsize; + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + rb->set_time(rb, nr_rlc_current_time); + /* UE does not seem to use saved_status_ind_tb_size */ + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + if (is_enb) + maxsize = ue->saved_status_ind_tb_size[channel_idP - 1]; + else + maxsize = tb_sizeP; + ret = rb->generate_pdu(rb, buffer_pP, maxsize); + } else { + LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + ret = 0; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + if (enb_flagP) + T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(rntiP), + T_INT(channel_idP), T_INT(ret)); + + return ret; +} + +mac_rlc_status_resp_t mac_rlc_status_ind( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) +{ + nr_rlc_ue_t *ue; + mac_rlc_status_resp_t ret; + nr_rlc_entity_t *rb; + + /* TODO: handle time a bit more properly */ + if (nr_rlc_current_time_last_frame != frameP || + nr_rlc_current_time_last_subframe != subframeP) { + nr_rlc_current_time++; + nr_rlc_current_time_last_frame = frameP; + nr_rlc_current_time_last_subframe = subframeP; + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + nr_rlc_entity_buffer_status_t buf_stat; + rb->set_time(rb, nr_rlc_current_time); + /* 36.321 deals with BSR values up to 3000000 bytes, after what it + * reports '> 3000000' (table 6.1.3.1-2). Passing 4000000 is thus + * more than enough. + */ + buf_stat = rb->buffer_status(rb, 4000000); + ret.bytes_in_buffer = buf_stat.status_size + + buf_stat.retx_size + + buf_stat.tx_size; + ue->saved_status_ind_tb_size[channel_idP - 1] = tb_sizeP; + } else { + ret.bytes_in_buffer = 0; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + ret.pdus_in_buffer = 0; + /* TODO: creation time may be important (unit: frame, as it seems) */ + ret.head_sdu_creation_time = 0; + ret.head_sdu_remaining_size_to_send = 0; + ret.head_sdu_is_segmented = 0; + return ret; +} + +int oai_emulation; + +rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + confirm_t confirmP, + sdu_size_t sdu_sizeP, + mem_block_t *sdu_pP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t *const sourceL2Id + ,const uint32_t *const destinationL2Id +#endif + ) +{ + int rnti = ctxt_pP->rnti; + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + + LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %ld mui %d confirm %d sdu_size %d MBMS_flag %d\n", + __FUNCTION__, rnti, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, + MBMS_flagP); + + if (ctxt_pP->enb_flag) + T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP)); + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + + rb = NULL; + + if (srb_flagP) { + if (rb_idP >= 1 && rb_idP <= 2) + rb = ue->srb[rb_idP - 1]; + } else { + if (rb_idP >= 1 && rb_idP <= 5) + rb = ue->drb[rb_idP - 1]; + } + + if (rb != NULL) { + rb->set_time(rb, nr_rlc_current_time); + rb->recv_sdu(rb, (char *)sdu_pP->data, sdu_sizeP, muiP); + } else { + LOG_E(RLC, "%s:%d:%s: fatal: SDU sent to unknown RB\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + free_mem_block(sdu_pP, __func__); + + return RLC_OP_STATUS_OK; +} + +int rlc_module_init(int enb_flag) +{ + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + static int inited = 0; + + if (pthread_mutex_lock(&lock)) abort(); + + if (inited) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + inited = 1; + + nr_rlc_ue_manager = new_nr_rlc_ue_manager(enb_flag); + + if (pthread_mutex_unlock(&lock)) abort(); + + return 0; +} + +void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP) +{ +} + +static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) +{ + nr_rlc_ue_t *ue = _ue; + int is_srb; + int rb_id; + protocol_ctxt_t ctx; + mem_block_t *memblock; + int i; + int is_enb; + + /* is it SRB? */ + for (i = 0; i < 2; i++) { + if (entity == ue->srb[i]) { + is_srb = 1; + rb_id = i+1; + goto rb_found; + } + } + + /* maybe DRB? */ + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + is_srb = 0; + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + +rb_found: + LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d", + __FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size); + + memblock = get_free_mem_block(size, __func__); + if (memblock == NULL) { + LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + memcpy(memblock->data, buf, size); + + /* unused fields? */ + ctx.instance = 0; + ctx.frame = 0; + ctx.subframe = 0; + ctx.eNB_index = 0; + ctx.configured = 1; + ctx.brOption = 0; + + /* used fields? */ + ctx.module_id = 0; + ctx.rnti = ue->rnti; + + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + ctx.enb_flag = is_enb; + + if (is_enb) { + T(T_ENB_RLC_UL, + T_INT(0 /*ctxt_pP->module_id*/), + T_INT(ue->rnti), T_INT(rb_id), T_INT(size)); + } + + if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock)) { + LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__); + /* what to do in case of failure? for the moment: nothing */ + } +} + +static void successful_delivery(void *_ue, nr_rlc_entity_t *entity, int sdu_id) +{ + nr_rlc_ue_t *ue = _ue; + int i; + int is_srb; + int rb_id; +#if 0 + MessageDef *msg; +#endif + int is_enb; + + /* is it SRB? */ + for (i = 0; i < 2; i++) { + if (entity == ue->srb[i]) { + is_srb = 1; + rb_id = i+1; + goto rb_found; + } + } + + /* maybe DRB? */ + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + is_srb = 0; + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + +rb_found: + LOG_D(RLC, "sdu %d was successfully delivered on %s %d\n", + sdu_id, + is_srb ? "SRB" : "DRB", + rb_id); + + /* TODO: do something for DRBs? */ + if (is_srb == 0) + return; + + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + if (!is_enb) + return; + +#if 0 + msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); + RLC_SDU_INDICATION(msg).rnti = ue->rnti; + RLC_SDU_INDICATION(msg).is_successful = 1; + RLC_SDU_INDICATION(msg).srb_id = rb_id; + RLC_SDU_INDICATION(msg).message_id = sdu_id; + /* TODO: accept more than 1 instance? here we send to instance id 0 */ + itti_send_msg_to_task(TASK_RRC_ENB, 0, msg); +#endif +} + +static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity) +{ + nr_rlc_ue_t *ue = _ue; + int i; + int is_srb; + int rb_id; +#if 0 + MessageDef *msg; +#endif + int is_enb; + + /* is it SRB? */ + for (i = 0; i < 2; i++) { + if (entity == ue->srb[i]) { + is_srb = 1; + rb_id = i+1; + goto rb_found; + } + } + + /* maybe DRB? */ + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + is_srb = 0; + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + +rb_found: + LOG_D(RLC, "max RETX reached on %s %d\n", + is_srb ? "SRB" : "DRB", + rb_id); + + /* TODO: do something for DRBs? */ + if (is_srb == 0) + return; + + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + if (!is_enb) + return; + +#if 0 + msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); + RLC_SDU_INDICATION(msg).rnti = ue->rnti; + RLC_SDU_INDICATION(msg).is_successful = 0; + RLC_SDU_INDICATION(msg).srb_id = rb_id; + RLC_SDU_INDICATION(msg).message_id = -1; + /* TODO: accept more than 1 instance? here we send to instance id 0 */ + itti_send_msg_to_task(TASK_RRC_ENB, 0, msg); +#endif +} + +static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) +{ + nr_rlc_entity_t *nr_rlc_am; + nr_rlc_ue_t *ue; + + struct LTE_SRB_ToAddMod__rlc_Config *r = s->rlc_Config; + struct LTE_SRB_ToAddMod__logicalChannelConfig *l = s->logicalChannelConfig; + int srb_id = s->srb_Identity; + int logical_channel_group; + + //int t_reordering; + int t_status_prohibit; + int t_poll_retransmit; + int poll_pdu; + int poll_byte; + int max_retx_threshold; + int t_reassembly; + int sn_field_length; + + if (srb_id != 1 && srb_id != 2) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n", + __FILE__, __LINE__, __FUNCTION__, srb_id); + exit(1); + } + + switch (l->present) { + case LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue: + logical_channel_group = *l->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup; + break; + case LTE_SRB_ToAddMod__logicalChannelConfig_PR_defaultValue: + /* default value from 36.331 9.2.1 */ + logical_channel_group = 0; + break; + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + /* TODO: accept other values? */ + if (logical_channel_group != 0) { + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + switch (r->present) { + case LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue: { + struct LTE_RLC_Config__am *am; + if (r->choice.explicitValue.present != LTE_RLC_Config_PR_am) { + LOG_E(RLC, "%s:%d:%s: fatal error, must be RLC AM\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + am = &r->choice.explicitValue.choice.am; + //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering); + t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); + t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); + poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); + poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte); + max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold); + break; + } + case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue: + /* default values from 36.331 9.2.1 */ + //t_reordering = 35; + t_status_prohibit = 0; + t_poll_retransmit = 45; + poll_pdu = -1; + poll_byte = -1; + max_retx_threshold = 4; + break; + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue->srb[srb_id-1] != NULL) { + LOG_D(RLC, "%s:%d:%s: warning SRB %d already exist for ue %d, do nothing\n", + __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); + } else { + /* hack: hardcode values for NR */ + t_poll_retransmit = 45; + t_reassembly = 35; + t_status_prohibit = 0; + poll_pdu = -1; + poll_byte = -1; + max_retx_threshold = 8; + sn_field_length = 12; + nr_rlc_am = new_nr_rlc_entity_am(100000, + 100000, + deliver_sdu, ue, + successful_delivery, ue, + max_retx_reached, ue, + t_poll_retransmit, + t_reassembly, t_status_prohibit, + poll_pdu, poll_byte, max_retx_threshold, + sn_field_length); + nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am); + + LOG_D(RLC, "%s:%d:%s: added srb %d to ue %d\n", + __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s) +{ + nr_rlc_entity_t *nr_rlc_am; + nr_rlc_ue_t *ue; + + struct LTE_RLC_Config *r = s->rlc_Config; + struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig; + int drb_id = s->drb_Identity; + int channel_id = *s->logicalChannelIdentity; + int logical_channel_group; + + //int t_reordering; + int t_status_prohibit; + int t_poll_retransmit; + int poll_pdu; + int poll_byte; + int max_retx_threshold; + int t_reassembly; + int sn_field_length; + + if (!(drb_id >= 1 && drb_id <= 5)) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id); + exit(1); + } + + if (channel_id != drb_id + 2) { + LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup; + + /* TODO: accept other values? */ + if (logical_channel_group != 1) { + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + switch (r->present) { + case LTE_RLC_Config_PR_am: { + struct LTE_RLC_Config__am *am; + am = &r->choice.am; + //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering); + t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); + t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); + poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); + poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte); + max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold); + break; + } + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue->drb[drb_id-1] != NULL) { + LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } else { + /* hack: hardcode values for NR */ + t_poll_retransmit = 45; + t_reassembly = 35; + t_status_prohibit = 0; + poll_pdu = -1; + poll_byte = -1; + max_retx_threshold = 8; + sn_field_length = 12; + nr_rlc_am = new_nr_rlc_entity_am(100000, + 100000, + deliver_sdu, ue, + successful_delivery, ue, + max_retx_reached, ue, + t_poll_retransmit, + t_reassembly, t_status_prohibit, + poll_pdu, poll_byte, max_retx_threshold, + sn_field_length); + nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am); + + LOG_D(RLC, "%s:%d:%s: added drb %d to ue %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s) +{ + nr_rlc_entity_t *nr_rlc_um; + nr_rlc_ue_t *ue; + + struct LTE_RLC_Config *r = s->rlc_Config; + struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig; + int drb_id = s->drb_Identity; + int channel_id = *s->logicalChannelIdentity; + int logical_channel_group; + + //int t_reordering; + int sn_field_length; + int t_reassembly; + + if (!(drb_id >= 1 && drb_id <= 5)) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id); + exit(1); + } + + if (channel_id != drb_id + 2) { + LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup; + + /* TODO: accept other values? */ + if (logical_channel_group != 1) { + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + switch (r->present) { + case LTE_RLC_Config_PR_um_Bi_Directional: { + struct LTE_RLC_Config__um_Bi_Directional *um; + um = &r->choice.um_Bi_Directional; + //t_reordering = decode_t_reordering(um->dl_UM_RLC.t_Reordering); + if (um->dl_UM_RLC.sn_FieldLength != um->ul_UM_RLC.sn_FieldLength) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + sn_field_length = decode_sn_field_length(um->dl_UM_RLC.sn_FieldLength); + break; + } + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue->drb[drb_id-1] != NULL) { + LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } else { + /* hack: hardcode values for NR */ + t_reassembly = 35; + sn_field_length = 6; + nr_rlc_um = new_nr_rlc_entity_um(1000000, + 1000000, + deliver_sdu, ue, + t_reassembly, + sn_field_length); + nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_um); + + LOG_D(RLC, "%s:%d:%s: added drb %d to ue %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) +{ + switch (s->rlc_Config->present) { + case LTE_RLC_Config_PR_am: + add_drb_am(rnti, s); + break; + case LTE_RLC_Config_PR_um_Bi_Directional: + add_drb_um(rnti, s); + break; + default: + LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, + const LTE_SRB_ToAddModList_t * const srb2add_listP, + const LTE_DRB_ToAddModList_t * const drb2add_listP, + const LTE_DRB_ToReleaseList_t * const drb2release_listP +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) +{ + int rnti = ctxt_pP->rnti; + int i; + + if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*|| + ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 || + ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) { + LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %d %d %d %d)\n", __FUNCTION__, + ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance, + ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption); + exit(1); + } + + if (pmch_InfoList_r9_pP != NULL) { + LOG_E(RLC, "%s: pmch_InfoList_r9_pP not handled\n", __FUNCTION__); + exit(1); + } + + if (drb2release_listP != NULL) { + LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (srb2add_listP != NULL) { + for (i = 0; i < srb2add_listP->list.count; i++) { + add_srb(rnti, srb2add_listP->list.array[i]); + } + } + + if (drb2add_listP != NULL) { + for (i = 0; i < drb2add_listP->list.count; i++) { + add_drb(rnti, drb2add_listP->list.array[i]); + } + } + + return RLC_OP_STATUS_OK; +} + +rlc_op_status_t rrc_rlc_config_req ( + const protocol_ctxt_t* const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t mbms_flagP, + const config_action_t actionP, + const rb_id_t rb_idP, + const rlc_info_t rlc_infoP) +{ + nr_rlc_ue_t *ue; + int i; + + if (mbms_flagP) { + LOG_E(RLC, "%s:%d:%s: todo (MBMS NOT supported)\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + if (actionP != CONFIG_ACTION_REMOVE) { + LOG_E(RLC, "%s:%d:%s: todo (only CONFIG_ACTION_REMOVE supported)\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + if (ctxt_pP->module_id) { + LOG_E(RLC, "%s:%d:%s: todo (only module_id 0 supported)\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + if ((srb_flagP && !(rb_idP >= 1 && rb_idP <= 2)) || + (!srb_flagP && !(rb_idP >= 1 && rb_idP <= 5))) { + LOG_E(RLC, "%s:%d:%s: bad rb_id (%ld) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); + exit(1); + } + nr_rlc_manager_lock(nr_rlc_ue_manager); + LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rnti); + if (srb_flagP) { + if (ue->srb[rb_idP-1] != NULL) { + ue->srb[rb_idP-1]->delete(ue->srb[rb_idP-1]); + ue->srb[rb_idP-1] = NULL; + } else + LOG_W(RLC, "removing non allocated SRB %ld, do nothing\n", rb_idP); + } else { + if (ue->drb[rb_idP-1] != NULL) { + ue->drb[rb_idP-1]->delete(ue->drb[rb_idP-1]); + ue->drb[rb_idP-1] = NULL; + } else + LOG_W(RLC, "removing non allocated DRB %ld, do nothing\n", rb_idP); + } + /* remove UE if it has no more RB configured */ + for (i = 0; i < 2; i++) + if (ue->srb[i] != NULL) + break; + if (i == 2) { + for (i = 0; i < 5; i++) + if (ue->drb[i] != NULL) + break; + if (i == 5) + nr_rlc_manager_remove_ue(nr_rlc_ue_manager, ctxt_pP->rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); + return RLC_OP_STATUS_OK; +} + +void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t rrc_data_confP) +{ + /* nothing to do */ +} + +rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) +{ + LOG_D(RLC, "%s:%d:%s: remove UE %d\n", __FILE__, __LINE__, __FUNCTION__, x->rnti); + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_manager_remove_ue(nr_rlc_ue_manager, x->rnti); + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return RLC_OP_STATUS_OK; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_pdu.c b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.c new file mode 100644 index 0000000000..b42410ab72 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.c @@ -0,0 +1,190 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_pdu.h" + +#include +#include + +#include "LOG/log.h" + +/**************************************************************************/ +/* RX PDU management */ +/**************************************************************************/ + +nr_rlc_pdu_t *nr_rlc_new_pdu(int sn, int so, int is_first, + int is_last, char *data, int size) +{ + nr_rlc_pdu_t *ret = malloc(sizeof(nr_rlc_pdu_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + ret->sn = sn; + ret->so = so; + ret->size = size; + ret->is_first = is_first; + ret->is_last = is_last; + ret->next = NULL; + + ret->data = malloc(size); + if (ret->data == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + memcpy(ret->data, data, size); + + return ret; +} + +void nr_rlc_free_pdu(nr_rlc_pdu_t *pdu) +{ + free(pdu->data); + free(pdu); +} + +nr_rlc_pdu_t *nr_rlc_pdu_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_pdu_t *list, nr_rlc_pdu_t *pdu) +{ + nr_rlc_pdu_t head; + nr_rlc_pdu_t *cur; + nr_rlc_pdu_t *prev; + + head.next = list; + cur = list; + prev = &head; + + /* order is by 'sn', if 'sn' is the same then order is by 'so' */ + while (cur != NULL) { + /* check if 'pdu' is before 'cur' in the list */ + if (sn_compare(sn_compare_data, cur->sn, pdu->sn) > 0 || + (cur->sn == pdu->sn && cur->so > pdu->so)) { + break; + } + prev = cur; + cur = cur->next; + } + prev->next = pdu; + pdu->next = cur; + return head.next; +} + +/**************************************************************************/ +/* PDU decoder */ +/**************************************************************************/ + +void nr_rlc_pdu_decoder_init(nr_rlc_pdu_decoder_t *decoder, + char *buffer, int size) +{ + decoder->error = 0; + decoder->byte = 0; + decoder->bit = 0; + decoder->buffer = buffer; + decoder->size = size; +} + +static int get_bit(nr_rlc_pdu_decoder_t *decoder) +{ + int ret; + + if (decoder->byte >= decoder->size) { + decoder->error = 1; + return 0; + } + + ret = (decoder->buffer[decoder->byte] >> (7 - decoder->bit)) & 1; + + decoder->bit++; + if (decoder->bit == 8) { + decoder->bit = 0; + decoder->byte++; + } + + return ret; +} + +int nr_rlc_pdu_decoder_get_bits(nr_rlc_pdu_decoder_t *decoder, int count) +{ + int ret = 0; + int i; + + if (count > 31) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + for (i = 0; i < count; i++) { + ret <<= 1; + ret |= get_bit(decoder); + if (decoder->error) return -1; + } + + return ret; +} + +/**************************************************************************/ +/* PDU encoder */ +/**************************************************************************/ + +void nr_rlc_pdu_encoder_init(nr_rlc_pdu_encoder_t *encoder, + char *buffer, int size) +{ + encoder->byte = 0; + encoder->bit = 0; + encoder->buffer = buffer; + encoder->size = size; +} + +static void put_bit(nr_rlc_pdu_encoder_t *encoder, int bit) +{ + if (encoder->byte == encoder->size) { + LOG_E(RLC, "%s:%d:%s: fatal, buffer full\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + encoder->buffer[encoder->byte] <<= 1; + if (bit) + encoder->buffer[encoder->byte] |= 1; + + encoder->bit++; + if (encoder->bit == 8) { + encoder->bit = 0; + encoder->byte++; + } +} + +void nr_rlc_pdu_encoder_put_bits(nr_rlc_pdu_encoder_t *encoder, + int value, int count) +{ + int i; + int x; + + if (count > 31) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + x = 1 << (count - 1); + for (i = 0; i < count; i++, x >>= 1) + put_bit(encoder, value & x); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_pdu.h b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.h new file mode 100644 index 0000000000..8e9872522f --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.h @@ -0,0 +1,84 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_PDU_H_ +#define _NR_RLC_PDU_H_ + +/**************************************************************************/ +/* RX PDU management */ +/**************************************************************************/ + +typedef struct nr_rlc_pdu_t { + int sn; + char *data; /* contains only SDU bytes, no PDU header */ + int size; /* size of SDU data, no PDU header bytes counted */ + int so; + int is_first; + int is_last; + struct nr_rlc_pdu_t *next; +} nr_rlc_pdu_t; + +nr_rlc_pdu_t *nr_rlc_new_pdu(int sn, int so, int is_first, + int is_last, char *data, int size); + +void nr_rlc_free_pdu(nr_rlc_pdu_t *pdu); + +nr_rlc_pdu_t *nr_rlc_pdu_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_pdu_t *list, nr_rlc_pdu_t *pdu); + +/**************************************************************************/ +/* PDU decoder */ +/**************************************************************************/ + +typedef struct { + int error; + int byte; /* next byte to decode */ + int bit; /* next bit in next byte to decode */ + char *buffer; + int size; +} nr_rlc_pdu_decoder_t; + +void nr_rlc_pdu_decoder_init(nr_rlc_pdu_decoder_t *decoder, + char *buffer, int size); + +#define nr_rlc_pdu_decoder_in_error(d) ((d)->error == 1) + +int nr_rlc_pdu_decoder_get_bits(nr_rlc_pdu_decoder_t *decoder, int count); + +/**************************************************************************/ +/* PDU encoder */ +/**************************************************************************/ + +typedef struct { + int byte; /* next byte to encode */ + int bit; /* next bit in next byte to encode */ + char *buffer; + int size; +} nr_rlc_pdu_encoder_t; + +void nr_rlc_pdu_encoder_init(nr_rlc_pdu_encoder_t *encoder, + char *buffer, int size); + +void nr_rlc_pdu_encoder_put_bits(nr_rlc_pdu_encoder_t *encoder, + int value, int count); + +#endif /* _NR_RLC_PDU_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c new file mode 100644 index 0000000000..ef0d52558a --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c @@ -0,0 +1,121 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_sdu.h" + +#include +#include + +#include "LOG/log.h" + +nr_rlc_sdu_segment_t *nr_rlc_new_sdu( + char *buffer, int size, + int upper_layer_id) +{ + nr_rlc_sdu_t *sdu = calloc(1, sizeof(nr_rlc_sdu_t)); + nr_rlc_sdu_segment_t *ret = calloc(1, sizeof(nr_rlc_sdu_segment_t)); + if (sdu == NULL || ret == NULL) + goto oom; + + sdu->ref_count = 1; + sdu->sn = -1; /* set later */ + sdu->upper_layer_id = upper_layer_id; + sdu->data = malloc(size); + if (sdu->data == NULL) + goto oom; + memcpy(sdu->data, buffer, size); + sdu->size = size; + sdu->retx_count = -1; + + ret->sdu = sdu; + ret->size = size; + ret->so = 0; + ret->is_first = 1; + ret->is_last = 1; + + return ret; + +oom: + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); +} + +void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu) +{ + sdu->sdu->ref_count--; + if (sdu->sdu->ref_count == 0) { + free(sdu->sdu->data); + free(sdu->sdu); + } + free(sdu); +} + +void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list, + nr_rlc_sdu_segment_t **end, + nr_rlc_sdu_segment_t *sdu) +{ + if (*list == NULL) { + *list = sdu; + *end = sdu; + return; + } + + (*end)->next = sdu; + *end = sdu; +} + +nr_rlc_sdu_segment_t *nr_rlc_sdu_segment_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment) +{ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + + head.next = list; + cur = list; + prev = &head; + + /* order is by 'sn', if 'sn' is the same then order is by 'so' */ + while (cur != NULL) { + /* check if 'sdu_segment' is before 'cur' in the list */ + if (sn_compare(sn_compare_data, cur->sdu->sn, sdu_segment->sdu->sn) > 0 || + (cur->sdu->sn == sdu_segment->sdu->sn && cur->so > sdu_segment->so)) { + break; + } + prev = cur; + cur = cur->next; + } + prev->next = sdu_segment; + sdu_segment->next = cur; + return head.next; +} + +void nr_rlc_free_sdu_segment_list(nr_rlc_sdu_segment_t *l) +{ + nr_rlc_sdu_segment_t *cur; + + while (l != NULL) { + cur = l; + l = l->next; + nr_rlc_free_sdu_segment(cur); + } +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h new file mode 100644 index 0000000000..f4585fb7d6 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h @@ -0,0 +1,56 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_SDU_H_ +#define _NR_RLC_SDU_H_ + +typedef struct nr_rlc_sdu_t { + int sn; + int upper_layer_id; + char *data; + int size; + int retx_count; + + int ref_count; /* incremented each time the SDU is segmented */ +} nr_rlc_sdu_t; + +typedef struct nr_rlc_sdu_segment_t { + nr_rlc_sdu_t *sdu; + int size; + int so; + int is_first; + int is_last; + struct nr_rlc_sdu_segment_t *next; +} nr_rlc_sdu_segment_t; + +nr_rlc_sdu_segment_t *nr_rlc_new_sdu( + char *buffer, int size, + int upper_layer_id); +void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu); +void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list, + nr_rlc_sdu_segment_t **end, + nr_rlc_sdu_segment_t *sdu); +nr_rlc_sdu_segment_t *nr_rlc_sdu_segment_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment); +void nr_rlc_free_sdu_segment_list(nr_rlc_sdu_segment_t *l); + +#endif /* _NR_RLC_SDU_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c new file mode 100644 index 0000000000..09f1e4f599 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c @@ -0,0 +1,190 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_ue_manager.h" + +#include +#include +#include + +#include "LOG/log.h" + +typedef struct { + pthread_mutex_t lock; + nr_rlc_ue_t **ue_list; + int ue_count; + int enb_flag; +} nr_rlc_ue_manager_internal_t; + +nr_rlc_ue_manager_t *new_nr_rlc_ue_manager(int enb_flag) +{ + nr_rlc_ue_manager_internal_t *ret; + + ret = calloc(1, sizeof(nr_rlc_ue_manager_internal_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + ret->enb_flag = enb_flag; + + return ret; +} + +int nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager_t *_m) +{ + nr_rlc_ue_manager_internal_t *m = _m; + return m->enb_flag; +} + +void nr_rlc_manager_lock(nr_rlc_ue_manager_t *_m) +{ + nr_rlc_ue_manager_internal_t *m = _m; + if (pthread_mutex_lock(&m->lock)) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +void nr_rlc_manager_unlock(nr_rlc_ue_manager_t *_m) +{ + nr_rlc_ue_manager_internal_t *m = _m; + if (pthread_mutex_unlock(&m->lock)) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +/* must be called with lock acquired */ +nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *_m, int rnti) +{ + /* TODO: optimze */ + nr_rlc_ue_manager_internal_t *m = _m; + int i; + + for (i = 0; i < m->ue_count; i++) + if (m->ue_list[i]->rnti == rnti) + return m->ue_list[i]; + + LOG_D(RLC, "%s:%d:%s: new UE %d\n", __FILE__, __LINE__, __FUNCTION__, rnti); + + m->ue_count++; + m->ue_list = realloc(m->ue_list, sizeof(nr_rlc_ue_t *) * m->ue_count); + if (m->ue_list == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + m->ue_list[m->ue_count-1] = calloc(1, sizeof(nr_rlc_ue_t)); + if (m->ue_list[m->ue_count-1] == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + m->ue_list[m->ue_count-1]->rnti = rnti; + + return m->ue_list[m->ue_count-1]; +} + +/* must be called with lock acquired */ +void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int rnti) +{ + nr_rlc_ue_manager_internal_t *m = _m; + nr_rlc_ue_t *ue; + int i; + int j; + + for (i = 0; i < m->ue_count; i++) + if (m->ue_list[i]->rnti == rnti) + break; + + if (i == m->ue_count) { + LOG_D(RLC, "%s:%d:%s: warning: ue %d not found\n", + __FILE__, __LINE__, __FUNCTION__, + rnti); + return; + } + + ue = m->ue_list[i]; + + for (j = 0; j < 2; j++) + if (ue->srb[j] != NULL) + ue->srb[j]->delete(ue->srb[j]); + + for (j = 0; j < 5; j++) + if (ue->drb[j] != NULL) + ue->drb[j]->delete(ue->drb[j]); + + free(ue); + + m->ue_count--; + if (m->ue_count == 0) { + free(m->ue_list); + m->ue_list = NULL; + return; + } + + memmove(&m->ue_list[i], &m->ue_list[i+1], + (m->ue_count - i) * sizeof(nr_rlc_ue_t *)); + m->ue_list = realloc(m->ue_list, m->ue_count * sizeof(nr_rlc_ue_t *)); + if (m->ue_list == NULL) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +/* must be called with lock acquired */ +void nr_rlc_ue_add_srb_rlc_entity(nr_rlc_ue_t *ue, int srb_id, nr_rlc_entity_t *entity) +{ + if (srb_id < 1 || srb_id > 2) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + srb_id--; + + if (ue->srb[srb_id] != NULL) { + LOG_E(RLC, "%s:%d:%s: fatal, srb already present\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ue->srb[srb_id] = entity; +} + +/* must be called with lock acquired */ +void nr_rlc_ue_add_drb_rlc_entity(nr_rlc_ue_t *ue, int drb_id, nr_rlc_entity_t *entity) +{ + if (drb_id < 1 || drb_id > 5) { + LOG_E(RLC, "%s:%d:%s: fatal, bad drb id\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + drb_id--; + + if (ue->drb[drb_id] != NULL) { + LOG_E(RLC, "%s:%d:%s: fatal, drb already present\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ue->drb[drb_id] = entity; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h new file mode 100644 index 0000000000..97da28cdce --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -0,0 +1,60 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_UE_MANAGER_H_ +#define _NR_RLC_UE_MANAGER_H_ + +#include "nr_rlc_entity.h" + +typedef void nr_rlc_ue_manager_t; + +typedef struct nr_rlc_ue_t { + int rnti; + /* due to openair calling status_ind/data_req, we need to keep this. + * To be considered 'hackish'. + */ + int saved_status_ind_tb_size[2+5]; + nr_rlc_entity_t *srb[2]; + nr_rlc_entity_t *drb[5]; +} nr_rlc_ue_t; + +/***********************************************************************/ +/* manager functions */ +/***********************************************************************/ + +nr_rlc_ue_manager_t *new_nr_rlc_ue_manager(int enb_flag); + +int nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager_t *m); + +void nr_rlc_manager_lock(nr_rlc_ue_manager_t *m); +void nr_rlc_manager_unlock(nr_rlc_ue_manager_t *m); + +nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *m, int rnti); +void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *m, int rnti); + +/***********************************************************************/ +/* ue functions */ +/***********************************************************************/ + +void nr_rlc_ue_add_srb_rlc_entity(nr_rlc_ue_t *ue, int srb_id, nr_rlc_entity_t *entity); +void nr_rlc_ue_add_drb_rlc_entity(nr_rlc_ue_t *ue, int drb_id, nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_UE_MANAGER_H_ */ diff --git a/openair2/LAYER2/nr_rlc/test.c b/openair2/LAYER2/nr_rlc/test.c new file mode 100644 index 0000000000..52b0891bc3 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/test.c @@ -0,0 +1,32 @@ +#include "nr_rlc_entity.h" + +#include + +int main(void) +{ + char out[32768]; + nr_rlc_entity_t *am; + int sdu_id = 0; + int size; + int i; + + am = new_nr_rlc_entity_am(100000, 100000, + 0, 0, + 0, 0, + 0, 0, + 45, 35, 0, + -1, -1, 8, + 12); + + char data[8] = { 1, 2, 3, 4, 8, 7, 6, 5 }; + + am->recv_sdu(am, data, sizeof(data), sdu_id++); + + size = am->generate_pdu(am, out, 32768); + + printf("generate_pdu[%d]:", size); + for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)out[i]); + printf("\n"); + + return 0; +} diff --git a/openair2/LAYER2/nr_rlc/tests/LOG/log.h b/openair2/LAYER2/nr_rlc/tests/LOG/log.h new file mode 100644 index 0000000000..5c9fcd643c --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/LOG/log.h @@ -0,0 +1,10 @@ +#ifndef _LOG_H_ +#define _LOG_H_ + +#include + +#define LOG_E(x, ...) printf(__VA_ARGS__) +#define LOG_D(x, ...) printf(__VA_ARGS__) +#define LOG_W(x, ...) printf(__VA_ARGS__) + +#endif /* _LOG_H_ */ diff --git a/openair2/LAYER2/nr_rlc/tests/Makefile b/openair2/LAYER2/nr_rlc/tests/Makefile new file mode 100644 index 0000000000..746d61483b --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/Makefile @@ -0,0 +1,33 @@ +CC=gcc +CFLAGS=-Wall -g --coverage -I. + +LIB=nr_rlc_entity.o nr_rlc_entity_am.o nr_rlc_entity_um.o nr_rlc_entity_tm.o \ + nr_rlc_pdu.o nr_rlc_sdu.o + +tests: + @./run_tests.sh + +all: clean_run $(TEST).run + +%.run: $(TEST).bin + #valgrind ./$(TEST).bin > $(TEST).run_pre 2> $(TEST).valgrind + ./$(TEST).bin > $(TEST).run_pre + grep ^TEST $(TEST).run_pre > $(TEST).run + gunzip -c $(TEST).txt.gz > $(TEST).txt + diff -q $(TEST).txt $(TEST).run + +$(TEST).bin: $(TEST).o $(LIB) + $(CC) $(CFLAGS) -o $@ $^ + +%.o: ../%.c + $(CC) $(CFLAGS) -I.. -c -o $@ $< + +$(TEST).o: test.c + $(CC) $(CFLAGS) -c -o $@ $< -DTEST='"$(TEST).h"' + +clean_run: + rm -f $(TEST).run $(TEST).bin $(TEST).o + +clean: + rm -f *.o *.bin *.run *.run_pre *.gcov *.gcda *.gcno test*.txt a.out \ + *.valgrind diff --git a/openair2/LAYER2/nr_rlc/tests/run_tests.sh b/openair2/LAYER2/nr_rlc/tests/run_tests.sh new file mode 100755 index 0000000000..ac22516064 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/run_tests.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +test_count=13 + +for i in `seq $test_count` +do + make all TEST=test$i >/dev/null 2>/dev/null + if [ $? != 0 ] + then + echo TEST $i FAILURE + fi +done diff --git a/openair2/LAYER2/nr_rlc/tests/test.c b/openair2/LAYER2/nr_rlc/tests/test.c new file mode 100644 index 0000000000..742e79ca2c --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test.c @@ -0,0 +1,483 @@ +#include "../nr_rlc_entity.h" +#include "../nr_rlc_entity_am.h" +#include "../nr_rlc_entity_um.h" +#include "../nr_rlc_entity_tm.h" + +#include +#include +#include +#include +#include +#include + +/* + * GNB_AM + * + * + * create the gNB RLC AM entity with given parameters + * + * UE_AM + * + * + * create the UE RLC AM entity with given parameters + * + * GNB_UM + * create the eNB RLC UM entity with given parameters + * + * UE_UM + * create the UE RLC UM entity with given parameters + * + * GNB_TM + * create the eNB RLC TM entity with given parameters + * + * UE_UM + * create the UE RLC TM entity with given parameters + * + * TIME